0

我第一次尝试虚拟 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);
        }
    }
}
4

1 回答 1

0

像这样处理 CellFormatting 事件而不是 RowPostPaint:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.RowIndex == 1 && e.ColumnIndex == 2)
    {
        e.CellStyle.ForeColor = Color.Red;
    }
}

只使用 CellStyle 属性,不要触摸dgv[col, row].Style属性,因为会再次触发事件。

于 2012-07-26T10:52:08.730 回答