2009-07-03 7 views
22

Mam datagridview składa się z wielu wierszy i kolumn. Chcę iterować w każdym wierszu i sprawdzić zawartość konkretnej kolumny. Jeśli ta kolumna zawiera słowo "NIE", chcę zmienić kolor początkowy całego wiersza na czerwony. Oto jak dotąd próba jakiegoś kodu, ale z pewnością nie działa, zaczyna się zastanawiać, czy muszę powtarzać każdą komórkę?C# Iterate Over DataGridView i zmień kolor wiersza

KOD:

foreach (DataGridViewRow dgvr in dataGridView1.Rows) 
     { 
      if (dgvr.Cells["FollowedUp"].Value.ToString() == ("No")) 
      { 
       dgvr.DefaultCellStyle.ForeColor = Color.Red; 
      } 
     } 
+1

Co to jest "nie działa"? Bez wierszy? komórki nie można znaleźć? – Colin

Odpowiedz

5
public void ColourChange() 
    { 
     DataGridViewCellStyle RedCellStyle = null; 
     RedCellStyle = new DataGridViewCellStyle(); 
     RedCellStyle.ForeColor = Color.Red; 
     DataGridViewCellStyle GreenCellStyle = null; 
     GreenCellStyle = new DataGridViewCellStyle(); 
     GreenCellStyle.ForeColor = Color.Green; 


     foreach (DataGridViewRow dgvr in dataGridView1.Rows) 
     { 
      if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No")) 
      { 
       dgvr.DefaultCellStyle = RedCellStyle; 
      } 
      if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("Yes")) 
      { 
       dgvr.DefaultCellStyle = GreenCellStyle; 
      } 
     } 
    } 
+10

Nic nie zyskujesz robiąc [Typ x = null; x = nowy typ();]. Powinieneś scalić te dwie linie w [Typ x = nowy typ();] –

25

zahaczyć OnRowDataBound wydarzenie wtedy robić rzeczy

ASPX (siatka):

<asp:.... OnRowDataBound="RowDataBound"..../> 

Code Behind:

protected void RowDataBound(object sender, GridViewRowEventArgs e) 
    { 
     if (e.Row.RowIndex == -1) 
     { 
      return; 
     } 

     if(e.Row.Cells[YOUR_COLUMN_INDEX].Text=="NO"){ 
      e.Row.BackColor=Color.Red; 
     } 
    } 

FOR WINForms:

hook the **DataBindingComplete** event and do stuff in it: 

    private void dataGridView1_DataBindingComplete(object sender, 
         DataGridViewBindingCompleteEventArgs e) 
    { 
     if (e.ListChangedType != ListChangedType.ItemDeleted) 
     { 
      DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone(); 
      red.BackColor=Color.Red; 

      foreach (DataGridViewRow r in dataGridView1.Rows) 
      { 
       if (r.Cells["FollowedUp"].Value.ToString() 
         .ToUpper().Contains("NO")) 
       { 
        r.DefaultCellStyle = red; 
       } 
      } 
     } 
    } 
+3

Przykro nam, że to tylko prosta aplikacja WinForms ......... – Goober

+1

oops! wszystko jest takie internetowe i jestem głęboko w projekcie internetowym od 3 miesięcy, że wydaje się normalne, że każde pytanie dotyczy asp.net – TheVillageIdiot

+0

ktoś nie głosował i nie wiem dlaczego? – TheVillageIdiot

2

Czy jest możliwe, że istnieją spacje lub inny znak jako część wartości komórki? Jeśli tak, spróbuj użyć metody Contains zamiast prostej równości.

if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No")) 
0

Jest to rozwiązanie dla WinForm:

private void HighlightRows() 
{ 
    DataGridViewCellStyle GreenStyle = null; 

    if (this.dgridv.DataSource != null) 
    { 
     RedCellStyle = new DataGridViewCellStyle(); 
     RedCellStyle.BackColor = Color.Red; 

     for (Int32 i = 0; i < this.dgridv.Rows.Count; i++) 
     { 
      if (((DataTable)this.dgridv.DataSource).Rows[i]["col_name"].ToString().ToUpper() == "NO") 
      { 
       this.dgridv.Rows[i].DefaultCellStyle = RedCellStyle; 
       continue; 
      } 
     } 
    } 
} 
+0

Brak wyjątku i Bez zmiany koloru. Nie wiem dlaczego potrzebuję pomocy –

0

Ten kod działa dobrze dla mnie:

 

foreach (DataGridViewRow row in dataGridView1.Rows) 
{ 
    if ((string)row.Cells["property_name"].Value == UNKNOWN_PROPERTY_NAME) 
    { 
     row.DefaultCellStyle.BackColor = Color.LightSalmon; 
     row.DefaultCellStyle.SelectionBackColor = Color.Salmon; 
    } 
} 
 

Inne niż odlewania jako ciąg zamiast wywołanie ToString ja naprawdę nie widzę żadnych różnicę, więc może to być błąd dotyczący wielkości liter. Spróbuj użyć:

 
dgvr.Cells["FollowedUp"].Value.ToString().ToUpper() == "NO" 
9

Na DataGridView, obsłużyć zdarzenia CellFormatting:

dataGridView1.CellFormatting += new DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting); 

Twój obsługi zdarzeń mógłby wyglądać następująco:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{  
    if(dataGridView1.Columns[e.ColumnIndex].Name == "FollowedUp" && e.Value != null && e.Value.ToString() == "No") 
     dataGridView1.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red; 
} 

W ten sposób Aren "t" iteracja "nad rzędami - po prostu zmieniając kolor, z którego są one malowane/rysowane, gdy stają się widoczne (i tym samym ponownie quire formatowanie) w siatce.

+0

Ta metoda jest wolniejsza, ale formatowanie nie zostanie wymazane przez sortowanie nagłówka kolumny. –

+0

Niestety coś było nie tak z podstawieniem kodu obsługi zdarzenia i nie mogę edytować poprzedniego komentarza. Zamieniłbym "DUŻO" na "nieco" wolniejszy. –

+0

W zależności od tego, co robisz w programie obsługi, większość tego (wydajności) będzie determinowana. Ostatecznie użycie metody obsługi oznacza (jak mówisz), że nie zostanie wyczyszczone przez sortowanie kolumn. Ale także w przypadku siatki z tysiącami rzędów nie "formatujesz" wierszy, których użytkownik nigdy nie zobaczy. – Rostov

0
private void Grd_Cust_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    colorCode == 4 ? Color.Yellow : Color.Brown; 
    if (e.RowIndex < 0 || Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value == DBNull.Value) 
     return; 
    string colorCode = Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value.ToString(); 
    e.CellStyle.BackColor = colorCode == "NO" ? Color.Red : Grd_Cust.DefaultCellStyle.BackColor; 
} 
+1

Witamy w stackoverflow. Wskazówka: możesz użyć przycisku '{} do sformatowania fragmentów kodu. – Leigh