Odpowiedzi:
Musisz przejrzeć wiersze w datagridview, a następnie porównać wartości z kolumn 7 i 10 w każdym wierszu.
Spróbuj tego:
foreach (DataGridViewRow row in vendorsDataGridView.Rows)
if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
Właśnie badałem ten problem (więc wiem, że to pytanie zostało opublikowane prawie 3 lata temu, ale może komuś pomoże ...), ale wydaje się, że lepszą opcją jest umieszczenie kodu wewnątrz RowPrePaint
wydarzenia, aby nie muszą przejść każdy wiersz, tylko te, które zostaną pomalowane (więc będzie działać znacznie lepiej na dużej ilości danych:
Dołącz do wydarzenia
this.dataGridView1.RowPrePaint
+= new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
this.dataGridView1_RowPrePaint);
Kod zdarzenia
private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[7].Text) < Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[10].Text))
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
}
Szukasz CellFormatting
wydarzenia.
Oto przykład.
Miałem również problem ze zmianą koloru tekstu - nigdy nie widziałem zmiany koloru.
Dopóki nie dodałem kodu, aby zmienić kolor tekstu wydarzenia DataBindingsComplete
dlaDataGridView
. Potem zadziałało.
Mam nadzieję, że pomoże to ludziom, którzy borykają się z tym samym problemem.
Coś podobnego do następującego ... zakładając, że wartości w komórkach są liczbami całkowitymi.
foreach (DataGridViewRow dgvr in myDGV.Rows)
{
if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
nieprzetestowane, więc przepraszamy za każdy błąd.
Jeśli znasz konkretny wiersz, możesz pominąć iterację:
if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Niektórzy ludzie lubią używać Paint
, CellPainting
lub CellFormatting
zdarzenia, ale pamiętać, że zmiana stylu w tych zdarzeń powoduje wywołań rekurencyjnych. Jeśli DataBindingComplete
go użyjesz , uruchomi się tylko raz. Argumentem za CellFormatting
jest to, że jest wywoływana tylko w widocznych komórkach, więc nie musisz formatować niewidocznych komórek, ale formatujesz je wielokrotnie.
Można zmienić Backcolor
wiersz po wierszu używając swojego condition.and to wywołanie funkcji po zastosowaniu Datasource
od DatagridView
.
Oto funkcja do tego. Po prostu skopiuj to i umieść późniejDatabind
private void ChangeRowColor()
{
for (int i = 0; i < gvItem.Rows.Count; i++)
{
if (BindList[i].MainID == 0 && !BindList[i].SchemeID.HasValue)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#C9CADD");
else if (BindList[i].MainID > 0 && !BindList[i].SchemeID.HasValue)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#DDC9C9");
else if (BindList[i].MainID > 0)
gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#D5E8D7");
else
gvItem.Rows[i].DefaultCellStyle.BackColor = Color.White;
}
}
private void dtGrdVwRFIDTags_DataSourceChanged(object sender, EventArgs e)
{
dtGrdVwRFIDTags.Refresh();
this.dtGrdVwRFIDTags.Columns[1].Visible = false;
foreach (DataGridViewRow row in this.dtGrdVwRFIDTags.Rows)
{
if (row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Lost"
|| row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Damaged"
|| row.Cells["TagStatus"].Value != null
&& row.Cells["TagStatus"].Value.ToString() == "Discarded")
{
row.DefaultCellStyle.BackColor = Color.LightGray;
row.DefaultCellStyle.Font = new Font("Tahoma", 8, FontStyle.Bold);
}
else
{
row.DefaultCellStyle.BackColor = Color.Ivory;
}
}
//for (int i= 0 ; i<dtGrdVwRFIDTags.Rows.Count - 1; i++)
//{
// if (dtGrdVwRFIDTags.Rows[i].Cells[3].Value.ToString() == "Damaged")
// {
// dtGrdVwRFIDTags.Rows[i].Cells["TagStatus"].Style.BackColor = Color.Red;
// }
//}
}
To jest moje rozwiązanie do zmiany koloru na dataGridView z bindingDataSource:
private void dataGridViewECO_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemDeleted)
{
DataGridViewCellStyle green = this.dataGridViewECO.DefaultCellStyle.Clone();
green.BackColor = Color.Green;
DataGridViewCellStyle gray = this.dataGridViewECO.DefaultCellStyle.Clone();
gray.BackColor = Color.LightGray;
foreach (DataGridViewRow r in this.dataGridViewECO.Rows)
{
if (r.Cells[8].Value != null)
{
String stato = r.Cells[8].Value.ToString();
if (!" Open ".Equals(stato))
{
r.DefaultCellStyle = gray;
}
else
{
r.DefaultCellStyle = green;
}
}
}
}
}
Jeśli utworzysz powiązanie z (kolekcją) konkretnych obiektów, możesz pobrać ten konkretny obiekt za pośrednictwem właściwości DataBoundItem wiersza. (Aby uniknąć sprawdzania magicznych ciągów w komórce i używania „rzeczywistych” właściwości obiektu)
Przykład szkieletu poniżej:
DTO / POCO
public class Employee
{
public int EmployeeKey {get;set;}
public string LastName {get;set;}
public string FirstName {get;set;}
public bool IsActive {get;set;}
}
Powiązanie z datagridview
private void BindData(ICollection<Employee> emps)
{
System.ComponentModel.BindingList<Employee> bindList = new System.ComponentModel.BindingList<Employee>(emps.OrderBy(emp => emp.LastName).ThenBy(emp => emp.FirstName).ToList());
this.dgvMyDataGridView.DataSource = bindList;
}
następnie program obsługi zdarzeń i pobieranie konkretnego obiektu (zamiast DataGridRow i / lub komórek)
private void dgvMyDataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
Employee concreteSelectedRowItem = this.dgvMyDataGridView.Rows[e.RowIndex].DataBoundItem as Employee;
if (null != concreteSelectedRowItem && !concreteSelectedRowItem.IsActive)
{
dgvMyDataGridView.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.LightGray;
}
}
Zazwyczaj lubię używać do tego zdarzenia zdarzenia GridView.RowDataBound.
protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.ForeColor = System.Drawing.Color.Red;
}
}
Działa na Visual Studio 2010. (Próbowałem i działa!) Pomaluje cały wiersz.
datagridview
.CellClick
wydarzenie i umieść w nim następną linię kodu.if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)
{
dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
Nie wspomniałeś, jak zmienia się wartość. Użyłem podobnej funkcji, gdy użytkownik wprowadza wartość. tj. wchodzenie i wychodzenie z trybu edycji.
Korzystanie ze zdarzenia CellEndEdit datagridview.
private void dgMapTable_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
double newInteger;
if (double.TryParse(dgMapTable[e.ColumnIndex,e.RowIndex].Value.ToString(), out newInteger)
{
if (newInteger < 0 || newInteger > 50)
{
dgMapTable[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Red;
dgMapTable[e.ColumnIndex, e.RowIndex].ErrorText
= "Keep value in Range:" + "0 to " + "50";
}
}
}
W podobny sposób możesz dodać logikę do usuwania powiadomień o błędach.
jeśli w twoim przypadku, jeśli dane są ładowane programowo, to zdarzenie CellLeave może być użyte z tym samym kodem.
Za pomocą tego kodu zmieniasz tylko kolor tła wierszy, w których wartość kolumny jest równa null, pozostałe wiersze są nadal kolorami domyślnymi.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["columnname"].Value != null)
{
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
}
}
Tylko uwaga na temat ustawienia DefaultCellStyle.BackColor
... nie możesz ustawić dla niego żadnej przezroczystej wartości oprócz Color.Empty
. To jest wartość domyślna. To fałszywie implikuje (przynajmniej dla mnie), że kolory przezroczyste są w porządku. Oni nie są. Każdy wiersz ustawiony na przezroczysty kolor rysuje tylko kolor wybranych wierszy.
Spędziłem o wiele za dużo czasu, uderzając głową o ścianę w tej sprawie.
Wylądowałem tutaj, szukając rozwiązania w przypadku, gdy nie używam wiązania danych. Nic mi nie pomogło, ale w końcu dostałem:
dataGridView.Columns.Clear();
dataGridView.Rows.Clear();
dataGridView.Refresh();
Jeśli jesteś drugim najgłupszym programistą na świecie (ja jestem najgłupszy), wszystkie powyższe rozwiązania wydają się działać: CellFormatting, DataSourceChanged i RowPrePaint. Wolę RowPrePaint.
Zmagałem się z tym (zbyt długo), ponieważ musiałem zastąpić moje SelectionBackColor i SelectionForeColor zamiast BackColor i ForeColor, gdy zmieniałem wybrany wiersz.
int counter = gridEstimateSales.Rows.Count;
for (int i = 0; i < counter; i++)
{
if (i == counter-1)
{
//this is where your LAST LINE code goes
//row.DefaultCellStyle.BackColor = Color.Yellow;
gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.Red;
}
else
{
//this is your normal code NOT LAST LINE
//row.DefaultCellStyle.BackColor = Color.Red;
gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.White;
}
}