无法绘制可滚动数据网格视图

Trouble painting scrollable datagridview

我正在尝试自定义绘制 DataGridView,但我无法让它在 DataGridView 滚动后立即显示。我的细胞中出现了线条。问题是当控件滚动时,绘制事件似乎不会重绘单元格,因此在窗体边缘绘制的单元格一旦滚动到中心就不会重绘。

我可以通过忽略 DataGridView 边缘的部分单元格未显示这一事实并将它们绘制为完全可见来消除该问题,但这会使我的应用程序看起来不那么漂亮。

我的问题是:是否有更好的方法来绘制 DataGridView,以便我可以针对部分显示的单元格调整我的单元格绘制?我查看了其他问题并尝试使用其他绘画事件,但我无法使任何工作正常进行。

这是一个简单的程序,它演示了我正在谈论的问题。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        for (int i = 0; i < 256; i++)
            dataGridView1.Rows.Add(new object[] { string.Format("Test_text_{0}", i) });

        dataGridView1.Paint += DataGridView1_Paint;
        dataGridView1.CellPainting += (s, e) => { if (e.RowIndex > 0 && e.ColumnIndex >= 0) e.Handled = true; };
    }

    private void DataGridView1_Paint(object sender, PaintEventArgs e)
    {
        Rectangle rect;

        using (Brush gridBrush = new SolidBrush(dataGridView1.GridColor),
            cellBrush = new SolidBrush(dataGridView1.DefaultCellStyle.BackColor),
            textBrush = new SolidBrush(dataGridView1.DefaultCellStyle.ForeColor))
        {
            using (Pen gridLinePen = new Pen(gridBrush))
            {
                for (int row = 0; row < dataGridView1.Rows.Count; row++)
                {
                    if (!dataGridView1.Rows[row].Displayed)
                        continue;

                    if (dataGridView1.Rows[row].Cells[0].Value != null)
                    {
                        //draw cell
                        rect = dataGridView1.GetCellDisplayRectangle(0, row, true);//Setting cutOverflow to false removes lines
                        e.Graphics.FillRectangle(cellBrush, rect);
                        e.Graphics.DrawLine(gridLinePen, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
                        e.Graphics.DrawLine(gridLinePen, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom);

                        //add text
                        e.Graphics.DrawString(dataGridView1.Rows[row].Cells[0].Value.ToString(), 
                            dataGridView1.DefaultCellStyle.Font, textBrush, rect.X + 4, rect.Y + 4);
                    }
                    else
                        //handle empty rows
                        e.Graphics.FillRectangle(gridBrush, dataGridView1.GetCellDisplayRectangle(0, row, true));
                }
            }
        }
    }
}

设计师代码

partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.dataGridView1 = new System.Windows.Forms.DataGridView();
        this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
        this.SuspendLayout();
        // 
        // dataGridView1
        // 
        this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
        this.Column1});
        this.dataGridView1.Location = new System.Drawing.Point(46, 36);
        this.dataGridView1.Name = "dataGridView1";
        this.dataGridView1.Size = new System.Drawing.Size(184, 428);
        this.dataGridView1.TabIndex = 0;
        // 
        // Column1
        // 
        this.Column1.HeaderText = "Column1";
        this.Column1.Name = "Column1";
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(281, 522);
        this.Controls.Add(this.dataGridView1);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.DataGridView dataGridView1;
    private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
}

这是截图

您已通过写入

禁用了单元格绘制
dataGridView1.CellPainting += (s, e) =>
    { if (e.RowIndex > 0 && e.ColumnIndex >= 0) e.Handled = true; };

使用 CellPainting 事件而不是 Paint 事件执行单元格绘制。

问题是 PaintCellPainting 事件都只绘制了在滚动 DataGridView 之前未显示的单元格部分。我能够通过在 Scroll 事件中强制重绘整个 DataGridView 来解决问题。

    dataGridView1.Scroll += (s, e) => dataGridView1.Invalidate();