Ответы:
Вам нужно перебрать строки в сетке данных, а затем сравнить значения столбцов 7 и 10 в каждой строке.
Попробуй это:
foreach (DataGridViewRow row in vendorsDataGridView.Rows)
if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
Я только что исследовал эту проблему (так что я знаю, что этот вопрос был опубликован почти 3 года назад, но, возможно, он кому-то поможет ...), но, похоже, что лучший вариант - разместить код внутри RowPrePaint
события, чтобы вы не могли придется проходить через все строки, только те, которые окрашены (поэтому он будет работать намного лучше при большом количестве данных:
Прикрепить к событию
this.dataGridView1.RowPrePaint
+= new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
this.dataGridView1_RowPrePaint);
Код события
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;
}
}
Вы ищете CellFormatting
событие.
Вот пример.
У меня также были проблемы с изменением цвета текста - я никогда не видел изменения цвета.
Пока я не добавил код, чтобы изменить цвет текста на событие DataBindingsComplete
для DataGridView
. После этого это сработало.
Я надеюсь, что это поможет людям, которые сталкиваются с той же проблемой.
Что-то вроде следующего ... при условии, что значения в ячейках являются целыми числами.
foreach (DataGridViewRow dgvr in myDGV.Rows)
{
if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
не проверено, поэтому извиняюсь за любую ошибку.
Если вы знаете конкретную строку, вы можете пропустить итерацию:
if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Некоторые люди любят использовать Paint
, CellPainting
или CellFormatting
события, но обратите внимание , что изменение стиля в этих событиях вызывают рекурсивные вызовы. Если вы используете DataBindingComplete
его, он будет выполнен только один раз. Аргументом для CellFormatting
является то, что он вызывается только для видимых ячеек, поэтому вам не нужно форматировать невидимые ячейки, но вы форматируете их несколько раз.
Вы можете изменить Backcolor
строку за строкой , используя ваш condition.and вызов этой функции после применения Datasource
в DatagridView
.
Вот функция для этого. Просто скопируйте это и поместите послеDatabind
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;
// }
//}
}
Это мое решение изменить цвет на dataGridView с 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;
}
}
}
}
}
Если вы привязываетесь к (коллекции) конкретных объектов, вы можете получить этот конкретный объект через свойство DataBoundItem строки. (Чтобы избежать проверки наличия магических строк в ячейке и использования «реальных» свойств объекта)
Пример скелета ниже:
DTO / ПОКО
public class Employee
{
public int EmployeeKey {get;set;}
public string LastName {get;set;}
public string FirstName {get;set;}
public bool IsActive {get;set;}
}
Привязка к сетке данных
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;
}
затем обработчик событий и получение конкретного объекта (вместо DataGridRow и / или ячеек)
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;
}
}
Я обычно хотел бы использовать событие GridView.RowDataBound Event для этого.
protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.ForeColor = System.Drawing.Color.Red;
}
}
Работает на Visual Studio 2010. (Я пробовал, и это работает!) Он будет рисовать весь ваш ряд.
datagridview
.CellClick
событие и поместите в него следующую строку кода.if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)
{
dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
Вы не упомянули, как изменяется значение. Я использовал аналогичные функции, когда пользователь вводит значение. т.е. вход и выход из режима редактирования.
Использование события 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";
}
}
}
Вы можете добавить логику для очистки уведомлений об ошибках аналогичным образом.
если в вашем случае, если данные загружаются программно, событие CellLeave можно использовать с тем же кодом.
С помощью этого кода вы изменяете только задний цвет строк, где значение столбца равно нулю, а цвет остальных строк остается цветом по умолчанию.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["columnname"].Value != null)
{
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
}
}
Просто примечание об установке DefaultCellStyle.BackColor
... вы не можете установить для него любое прозрачное значение, кроме Color.Empty
. Это значение по умолчанию. Это ложно подразумевает (для меня, во всяком случае), что прозрачные цвета в порядке. Они не. Каждая строка, которую я установил в прозрачный цвет, просто рисует цвет выделенных строк.
Я потратил слишком много времени, стуча головой об стену из-за этой проблемы.
Я приземлился здесь в поисках решения для случая, когда я не использую привязку данных. Ничто не сработало для меня, но я получил это в конце концов с:
dataGridView.Columns.Clear();
dataGridView.Rows.Clear();
dataGridView.Refresh();
Если вы являетесь вторым самым глупым разработчиком на планете (а я самым глупым), кажется, что все вышеперечисленные решения работают: CellFormatting, DataSourceChanged и RowPrePaint. Я предпочитаю RowPrePaint.
Я боролся с этим (слишком долго), потому что мне нужно было переопределить мои SelectionBackColor и SelectionForeColor вместо BackColor и ForeColor, когда я менял выбранную строку.
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;
}
}