我第一次尝试虚拟 DataGridView 时遇到了一个奇怪的问题。网格显示来自 DataTable 的数据,并且根据状态列的值对行进行颜色编码。我使用事件RowPostPaint根据其状态值设置每行的颜色。
只要网格中的行在所有列中都具有相同的颜色,这将非常有效。但是当我每行引入一种以上的颜色时,网格会变得疯狂并连续触发 CellValueNeeded 事件,并且 CPU 使用率会上升到 100%。一旦多色行滚动出视图,问题就会消失。
DataGridView 在常规模式下没有问题。但是,我真的很想使用虚拟 DataGridView 来实现最佳性能。有谁知道这个问题以及如何避免它?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
namespace VirtualDGV
{
public partial class Form1 : Form
{
protected Color greenColor = Color.FromArgb(200, 240, 140);
protected Color redColor = Color.FromArgb(255, 100, 50);
protected Color cyanColor = Color.FromArgb(175, 255, 225);
protected Color pinkColor = Color.FromArgb(255, 200, 150);
private DataTable data = null;
public Form1()
{
InitializeComponent();
LoadData2();
dgv.VirtualMode = true;
dgv.CellValueNeeded += new DataGridViewCellValueEventHandler(dgv_CellValueNeeded);
dgv.RowPostPaint += new DataGridViewRowPostPaintEventHandler(dgv_RowPostPaint);
}
private void CreateDataTable()
{
if (data != null)
{
data.Clear();
data.Dispose();
data = null;
}
data = new DataTable();
List<DataColumn> columns = new List<DataColumn>();
columns.Add(new DataColumn("A", typeof(string)));
columns.Add(new DataColumn("B", typeof(string)));
columns.Add(new DataColumn("C", typeof(DateTime)));
columns.Add(new DataColumn("D", typeof(DateTime)));
columns.Add(new DataColumn("E", typeof(string)));
columns.Add(new DataColumn("F", typeof(double)));
columns.Add(new DataColumn("G", typeof(double)));
columns.Add(new DataColumn("H", typeof(string)));
columns.Add(new DataColumn("I", typeof(string)));
columns.Add(new DataColumn("J", typeof(int)));
columns.Add(new DataColumn("Status", typeof(int)));
data.Columns.AddRange(columns.ToArray());
}
private void LoadData1()
{
CreateDataTable();
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 2);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 1);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 5);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 5);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 5);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
dgv.RowCount = data.Rows.Count;
}
private void LoadData2()
{
CreateDataTable();
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 9);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
data.Rows.Add("Abcdefghijklmnopqrstuvwxyz", "XYZ", DateTime.Now, DateTime.Now, "ZZZ", 110, 110, "", "", 250, 0);
dgv.RowCount = data.Rows.Count;
}
protected void SetRowColor(DataGridViewRow row, int status, int dateColumn, int amountColumn)
{
switch (status)
{
case 10:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = greenColor;
row.Cells[dateColumn].Style.BackColor = Color.FromArgb(255, 170, 130);
break;
case 11:
row.Cells[dateColumn].Style.BackColor = Color.FromArgb(255, 170, 130);
row.Cells[amountColumn].Style.BackColor = greenColor;
break;
case 1:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = greenColor;
break;
case 2:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = greenColor;
row.Cells[amountColumn].Style.BackColor = pinkColor;
break;
case 3:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = greenColor;
row.Cells[dateColumn].Style.BackColor = Color.FromArgb(255, 170, 130);
break;
case 4:
row.Cells[dateColumn].Style.BackColor = Color.FromArgb(255, 170, 130);
row.Cells[amountColumn].Style.BackColor = Color.FromArgb(255, 200, 150);
break;
case 5:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = redColor;
break;
case 6:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = cyanColor;
break;
case 7:
row.Cells[amountColumn].Style.BackColor = greenColor;
break;
case 8:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = cyanColor;
break;
case 9:
for (int i = 1; i < row.Cells.Count; i++)
row.Cells[i].Style.BackColor = greenColor;
row.Cells[dateColumn].Style.BackColor = redColor;
row.Cells[amountColumn].Style.BackColor = redColor;
break;
}
}
private void dgv_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
//Debug.WriteLine(e.RowIndex + ", " + e.ColumnIndex);
e.Value = data.Rows[e.RowIndex][e.ColumnIndex];
}
private void dgv_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
SetRowColor(dgv.Rows[e.RowIndex], (int)data.Rows[e.RowIndex]["Status"], 4, 7);
}
}
}