首页 > 解决方案 > DataGridView 中重写的 CellPainting 仅在单元格失去焦点后才显示内容

问题描述

我已经覆盖了 WinForms DataGridView 中的 CellPainting,以根据各种因素在单元格中显示特定图像。

为您提供更多详细信息,在 CellPainting 中,我正在重绘 DataGricViewCheckBoxColumn 的内容;我想显示一个绿色勾号或红十字,而不是默认的黑色勾号。

要绘制我使用的图像:

e.Graphics.DrawImage(image, new PointF(centreX - offsetX, centreY - offsetY));

它工作正常,但我的绿色勾号/红十字会仅在单元格失去焦点后显示。有没有办法让它在我点击后立即显示,就像标准复选框一样?

谢谢

标签: winformscheckboxdatagridview

解决方案


处理CellContentClick事件以切换当前单元格的值(真/假)。a的CellContentDataGridViewCheckBoxColumn是复选框。

假设DataGridViewCheckBoxColumn是第一列:

private void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex >= 0)
    {
        var s = sender as DataGridView;
        var b = s[e.ColumnIndex, e.RowIndex].Value == null
            ? true
            : (bool)s[e.ColumnIndex, e.RowIndex].Value;

        s[e.ColumnIndex, e.RowIndex].Value = !b;
    }
}

如果您希望通过单击单元格上的任意位置(而不是仅在复选框上)来切换值,请CellMouseClick改为处理:

private void dgv_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && e.ColumnIndex == 0 && e.RowIndex >= 0)
    {
        var s = sender as DataGridView;
        var b = s[e.ColumnIndex, e.RowIndex].Value == null
            ? true 
            : (bool)s[e.ColumnIndex, e.RowIndex].Value;

        s[e.ColumnIndex, e.RowIndex].Value = !b;
        s.NotifyCurrentCellDirty(true);
    }
}

无论哪种方式,CellPainting事件都会触发并在您单击时绘制指定的图像。

CellPainting例子:

Bitmap bmp1 = Properties.Resources.GreenImage;
Bitmap bmp2 = Properties.Resources.RedImage;

private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex >= 0)
    {
        var s = sender as DataGridView;

        e.Paint(e.CellBounds, DataGridViewPaintParts.Background
            | DataGridViewPaintParts.Border
            | DataGridViewPaintParts.SelectionBackground
            | DataGridViewPaintParts.Focus
            | DataGridViewPaintParts.ErrorIcon);

        if (e.Value != null)
        {
            var r = new Rectangle((e.CellBounds.Width - 16) / 2 + e.CellBounds.X,
                (e.CellBounds.Height - 16) / 2 + e.CellBounds.Y, 16, 16);
            var b = (bool)e.Value;

            e.Graphics.DrawImage(b ? bmp1 : bmp2, r);
        }

        e.Handled = true;
    }
}

推荐阅读