如何在 datagridview 中更改行颜色

我想在 datagridview 中更改特定行的颜色。当 column cell 7的值小于 column cell 10中的值时,该行应更改为红色。对于如何实现这一点有什么建议吗?

485982 次浏览

你要找的是 CellFormatting事件。
这里 是一个例子。

如下所示... 假设单元格中的值是整数。

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;
}

您需要遍历 datagridview 中的行,然后比较每一行上的列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;
}

我通常喜欢为此使用 GridView.RowDataBound 事件事件。

protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.ForeColor = System.Drawing.Color.Red;
}
}
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;
//    }
//}
}

我只是在研究这个问题(所以我知道这个问题大约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;
}
}

我在改变文本颜色方面也遇到了麻烦——我从来没有看到颜色的变化。

直到我为 DataGridView添加了将文本颜色更改为事件 DataBindingsComplete的代码。

我希望这能帮助那些面临同样问题的人。

有些人喜欢使用 PaintCellPaintingCellFormatting事件,但是请注意,更改这些事件中的样式会导致递归调用。如果使用 DataBindingComplete,它将只执行一次。CellFormatting的理由是,它只在可见单元格上调用,因此不必格式化不可见单元格,但需要多次格式化它们。

在应用 DatagridViewDatasource之后,您可以使用条件函数和此函数调用一行一行地更改 Backcolor

这是它的函数。 只要复制它,并把它后面的 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;
}
}

可以在 VisualStudio2010上工作。(我试过了,它可以工作!) 它会画满你的整排。

  1. datagridview创建一个按钮。
  2. 创建一个 CellClick事件并将下一行代码放入其中。

if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)
{
dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}

你没有提到价值是如何改变的。当用户输入值时,我使用了类似的功能。即进入和离开编辑模式。

使用 datagridview 的 CellEndEdit事件。

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";
}
}
}

您可以以类似的方式添加清除错误通知的逻辑。

如果在您的情况下,数据是以编程方式加载的,那么 手机离开事件可以与相同的代码一起使用。

这是我使用 bindingDataSource 将颜色更改为 dataGridView 的解决方案:

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;
}
}


}


}
}

使用此代码,您只需更改列名值为空的行的背景颜色,其他行的颜色仍然是默认颜色。

       foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["columnname"].Value != null)
{
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
}
}

只是一个关于设置 DefaultCellStyle.BackColor的注意事项... 你不能将它设置为除 Color.Empty之外的任何透明值。这是默认值。这错误地暗示(至少对我来说)透明的颜色是可以的。他们不是。我设置为透明颜色的每一行只是绘制所选行的颜色。

在这个问题上,我花了太多的时间在撞墙上。

如果绑定到具体对象的(集合) ,则可以通过行的 Databound Item 属性获取该具体对象。(避免检查单元格中的魔术字符串并使用对象的“ real”属性)

下面是一个很好的例子:

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;}
}

绑定到 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;
}

然后是事件处理程序并获取具体的对象(而不是 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;
}
}
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;
}
}

我来到这里是为了寻找一个不使用数据绑定的解决方案。对我来说什么都不管用,但我最终得到了它:

dataGridView.Columns.Clear();
dataGridView.Rows.Clear();
dataGridView.Refresh();

如果您是这个星球上第二笨的开发人员(我是最笨的) ,那么上述所有解决方案似乎都可以工作: CellFormatting、 DataSourceChanged 和 RowPrePaint。我更喜欢 RowPrePaint。

我纠结于此(太长时间了) ,因为我需要覆盖我的 SelectionBackColor 和 SelectionForeColor,而不是 BackColor 和 ForeColor,因为我正在更改选定的行。

dataGridView1.Rows[1].Cells[1].Style.BackColor = Color.Yellow;




    

如果(this. dgblista. Columns [ e. ColumnIndex ] . Name = = “ TOTAL PAGADO”) { ((dgblista. Columns [ e. ColumnIndex ] . Name = = “ COSTO DEL CURSO”) = = (dgblista. Columns [ e. ColumnIndex ] . Name = = “ TOTAL PAGADO”)) { 细胞风格。前色 = 颜色。白色; 背色 = 颜色。红色; } }