using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridViewCellFormatting1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
dataGridView1.DataSource = MockedDataTable.Table();
dataGridView1.CellFormatting += DataGridView1OnCellFormatting;
}
private const string _amountColumnName = "Amount";
private void DataGridView1OnCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (!dataGridView1.Columns[e.ColumnIndex].Name.Equals(_amountColumnName)) return;
if (e.Value == null || !int.TryParse(e.Value.ToString(), out var amount)) return;
dataGridView1.Rows[e.RowIndex].Cells[_amountColumnName].Style.BackColor = amount >0 ?
Color.Empty :
Color.Red;
}
}
public class MockedDataTable
{
public static DataTable Table()
{
var dt = new DataTable();
dt.Columns.Add(new DataColumn()
{
ColumnName = "id",
DataType = typeof(int),
AutoIncrement = true,
AutoIncrementSeed = 1
});
dt.Columns.Add(new DataColumn() { ColumnName = "Amount", DataType = typeof(int) });
dt.Rows.Add(null, 200);
dt.Rows.Add(null, 1000);
dt.Rows.Add(null, -3200);
dt.Rows.Add(null, -300);
dt.Rows.Add(null, 500);
return dt;
}
}
}
e.Value == null
之外,还应该检查 DBNull.Value
的值。 - JimiDBNull.Value
的内容。 - Karen Payne看着你想要的输出:
你并不想改变整个列的背景颜色,而是想改变包含小于零的值的单元格的颜色。
MyDataGrid.Rows
)来完成。每一行都是DataGridViewRow
类型,因此可以通过列位置访问每个单元格 - row.Cells[i]
。每个单元格都是DataGridViewCell
类型。在那里,您可以检查单元格的Value
属性。
更动态的方法是迭代所有行的所有单元格(row.Cells
),并检查cell.OwningColumn
的标题。如果它等于您想要的列标题,则可以检查单元格的值。如果符合您的条件,可以通过定位底层样式-例如cell.Style.BackColor = Color.Red;
来开始着色背景颜色。
public partial class Form1 : Form
{
private readonly DataGridView _myGrid;
public Form1()
{
InitializeComponent();
this.Load += this.Form1_Load;
_myGrid = new DataGridView
{
DataSource = new[]
{
new {Name = "ABC", Amount = 2}, new {Name = "DEF", Amount = 3}, new {Name = "XYZ", Amount = -2}
}
};
this.Controls.Add(_myGrid);
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (DataGridViewRow row in _myGrid.Rows)
{
var cell = row.Cells[1];
if (cell.Value is int val && val < 0)
{
cell.Style.BackColor = Color.Red;
}
// A little bit more secure, if you are not sure which index the column has.
/*
foreach (DataGridViewCell cell in row.Cells)
{
if (string.Equals(cell.OwningColumn.HeaderText, "Amount"))
{
if (cell.Value is int val && val < 0)
{
cell.Style.BackColor = Color.Red;
}
}
}
*/
}
}
}
回应您的评论:
我正在使用1.0版本[...] 但是有一个问题,我的数据网格的数据源来自SQL Server。 因此,如果列中有任何空值,程序会崩溃。 我该如何避免崩溃?
您可以使用int val = Convert.ToInt32(cell.Value);
而不是模式匹配。为了避免在null
值上出现System.NullReferenceExeption
,您可以添加一个null
检查。
如果从数据库接收到null
值,则可能是DBNull.Value
,它不等于null
,因此您可以添加一个DBNull
检查。
if (cell.Value == null || DBNull.Value.Equals(cell.Value))
{
continue;
}
int val = Convert.ToInt32(cell.Value);
if (val < 0)
{
cell.Style.BackColor = Color.Red;
}
System.FormatException
,如果你的列中可能包含除整数以外的内容,你可以使用 Int32.TryParse
而不是 Convert.ToInt32()
- 同时进行空值检查。 int val;
if (Int32.TryParse(cell.Value.ToString(), out val))
{
if (val < 0)
{
cell.Style.BackColor = Color.Red;
}
}
但要小心:虽然Convert.ToInt32(cell.Value)
也会将十进制数转换为int
,但Int32.TryParse(cell.Value.ToString(), out val)
会返回false
。
网站注释: 有更智能的解决方案,但这是我首先想到的。
int val = Convert.ToInt32(cell.Value);
。 - Martin Backasch
col
是DataGridViewColumn,它没有索引器:col [5]
没有意义。您正在尝试获取Cell.Value,因此请迭代行,最终 - 看起来您不想更改整个列的颜色,而是特定值具有特定值的特定单元格的背景颜色。请注意,5
实际上是正确的列:使用名称而不是索引(如MyDataGrid ["SomeColumnName", e.RowIndex]
)-澄清意图。 - Jimi