为什么连续调用 RowPrePaint?
Why is RowPrePaint being called continuously?
我有一个 DataGridView
并像这样实现了 RowPrePaint
事件:
private void dgData_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
int multiplier = (int)dgData.Rows[e.RowIndex].Cells["multiplier"].Value;
bool marked = (bool)(dgData.Rows[e.RowIndex].Tag ?? false);
if (multiplier > 1)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.FromArgb(0xff, 0xf2, 0xf2, 0xff);
}
if (marked)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.FromArgb(0xff, 0xff, 0xff, 0xf2);
}
}
当我拥有所有这些代码时,我可以看到我的网格正在不断地重新绘制(添加日志语句时确认)。当我注释掉代码时,只在需要时才重新绘制。
为什么会这样?
通过更改 RowPrePaint
事件中的单元格样式,您实际上是在要求该行重新绘制自身,从而再次触发所述事件。如果颜色每次都改变,这甚至可以无限期地重复,如下面的代码所示:
private static Random random = new Random();
private void dgData_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor =
Color.FromArgb(random.Next(0, 256), 0xf2, 0xf2, 0xff);
}
针对您的具体情况,我可以想到两种更改单元格样式的方法。
如果您需要更改行的实际 DefaultCellStyle
,并且由于颜色是(部分)根据单元格值确定的,您可以处理 CellValueChanged
事件。假设行的 Tag
属性 没有改变,你就可以开始了。否则,您需要在更改行标记后执行相同的代码。
如果您只想更改显示的颜色,您可以使用 CellFormatting
事件,该事件通过其 EventArgs 公开 DataGridViewCellStyle
属性。不要在那个事件中改变 DefaultCellStyle
,否则,你会遇到同样的问题(重新触发同样的事件)。相反,您可以使用 e.CellStyle
来达到相同的目的:
private void dgData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
e.CellStyle.BackColor = Color.FromArgb(...);
}
我有一个 DataGridView
并像这样实现了 RowPrePaint
事件:
private void dgData_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
int multiplier = (int)dgData.Rows[e.RowIndex].Cells["multiplier"].Value;
bool marked = (bool)(dgData.Rows[e.RowIndex].Tag ?? false);
if (multiplier > 1)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.FromArgb(0xff, 0xf2, 0xf2, 0xff);
}
if (marked)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.FromArgb(0xff, 0xff, 0xff, 0xf2);
}
}
当我拥有所有这些代码时,我可以看到我的网格正在不断地重新绘制(添加日志语句时确认)。当我注释掉代码时,只在需要时才重新绘制。
为什么会这样?
通过更改 RowPrePaint
事件中的单元格样式,您实际上是在要求该行重新绘制自身,从而再次触发所述事件。如果颜色每次都改变,这甚至可以无限期地重复,如下面的代码所示:
private static Random random = new Random();
private void dgData_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
dgData.Rows[e.RowIndex].DefaultCellStyle.BackColor =
Color.FromArgb(random.Next(0, 256), 0xf2, 0xf2, 0xff);
}
针对您的具体情况,我可以想到两种更改单元格样式的方法。
如果您需要更改行的实际
DefaultCellStyle
,并且由于颜色是(部分)根据单元格值确定的,您可以处理CellValueChanged
事件。假设行的Tag
属性 没有改变,你就可以开始了。否则,您需要在更改行标记后执行相同的代码。如果您只想更改显示的颜色,您可以使用
CellFormatting
事件,该事件通过其 EventArgs 公开DataGridViewCellStyle
属性。不要在那个事件中改变DefaultCellStyle
,否则,你会遇到同样的问题(重新触发同样的事件)。相反,您可以使用e.CellStyle
来达到相同的目的:private void dgData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { e.CellStyle.BackColor = Color.FromArgb(...); }