【问题标题】:How do I handle painting for a DataGridView's editing control?如何处理 DataGridView 编辑控件的绘制?
【发布时间】:2010-11-26 05:50:08
【问题描述】:

我有一个DataGridView,并且在其RowPostPaint 事件期间,我在每行的第一个单元格上绘制 TreeView 样式的虚线。当第一个单元格(DataGridViewTextBoxCell)处于编辑模式时,不会绘制线条。如何处理编辑控件的绘画?标准编辑控件没有 Paint 事件,如果可以避免的话,我不想创建新类型的单元格。

【问题讨论】:

  • 我刚刚遇到了与您完全相同的问题,同时尝试向选定的单元格添加类似 Excel 的字形。使用编辑控件时不会调用绘画事件。我目前正在研究使用 PositionEditingPanel 属性来缩小编辑控件,使其不会干扰父单元格中的字形。如果我破解它,我会回帖。

标签: c# .net winforms datagridview


【解决方案1】:

首先将第一列的单元格内边距设置为左起 16,因此在查看模式或编辑模式下,内容将使用给定的内边距显示。

this.dataGridView1.Columns[0].DefaultCellStyle.Padding= new Padding(16,0,0,0);

然后处理CellPainting事件并执行以下步骤:

  1. 只绘制第一列并且 RowIndex 应该 >=0 以避免呈现列标题
  2. 画出你的树线或任何你想要的东西
  3. 使用 e.Handled = true 取消默认绘制

代码如下:

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //Only paint rirst column and RowIndex should be >=0 to avoid rendering column header
    if (e.ColumnIndex == 0 & e.RowIndex >= 0)
    {
        //Paint your tree lines or whatever you want
        using (var treePen = new Pen(Color.Gray, 1))
        {
            treePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
            e.Paint(e.CellBounds, DataGridViewPaintParts.All);
            e.Graphics.DrawLine(treePen,
                new Point(e.CellBounds.Left + 4, e.CellBounds.Top),
                new Point(e.CellBounds.Left + 4, e.CellBounds.Bottom));

            e.Graphics.DrawLine(treePen,
                new Point(e.CellBounds.Left + 4, e.CellBounds.Top + e.CellBounds.Height / 2),
                new Point(e.CellBounds.Left + 12, e.CellBounds.Top + e.CellBounds.Height / 2));
        }

        //Cancel default painting using e.Handled = true
        e.Handled = true;
    }
}

这是截图:

【讨论】:

  • e.Handled 设置为 true 是危险的。设置 DataGridViewTextBoxCell 的值将覆盖它,调整大小不会过度绘制所有内容并留下一团糟。更好的解决方案在这里:stackoverflow.com/a/35553181/419581
【解决方案2】:

我通过创建自定义单元格类型解决了类似的问题,并按照 Bryan 的描述缩小了编辑控件。这并不是很困难,而且这是我知道的唯一方法,可以防止编辑控件在所有内容之上绘制。

这样的东西应该对你有用:

public class PaintAccommodatingTextBoxCell : DataGridViewTextBoxCell
{
    // Adjust the editing panel, so that custom painting isn't
    // drawn over when cells go into edit mode.
    public override Rectangle PositionEditingPanel(Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
    {
        // First, let base class do its adjustments
        Rectangle controlBounds = base.PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);

        // Shrink the bounds here...

        return controlBounds;
    }
}

public class PaintAccommodatingTextBoxColumn : DataGridViewTextBoxColumn
{
    PaintAccommodatingTextBoxCell templateCell;

    public PaintAccommodatingTextBoxColumn()
    {
        templateCell = new PaintAccommodatingTextBoxCell();
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return templateCell;
        }
        set
        {
            PaintAccommodatingTextBoxCell newTemplate = value as PaintAccommodatingTextBoxCell;
            if (newTemplate == null)
                throw new ArgumentException("Template must be a PaintAccommodatingTextBoxCell");
            else
                templateCell = newTemplate;
        }
    }
}

【讨论】:

  • 在处理同一问题时,我发现在调用 base.PositionEditingPanel 之前需要修改 cellBounds 参数,而不是简单地修改返回值。否则 EditingControl 将被调整大小,但 EditingPanel 不会调整大小,这会掩盖自定义单元格的绘制。
【解决方案3】:

尝试处理 DataGridView.CellPainting 事件。

【讨论】:

  • 不高兴 - 它被调用了,但是当单元格处于编辑模式时它不会绘制任何可见的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2010-10-15
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多