Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I handle painting for a DataGridView's editing control?

I have a DataGridView and I'm drawing TreeView-style dotted lines on the first cell of each row during its RowPostPaint event. When the first cell (which is a DataGridViewTextBoxCell) is in editing mode, the lines aren't drawn. How do I handle painting for the editing control? The standard editing control doesn't have a Paint event, and I don't want to create a new type of cell if I can avoid doing so.

like image 734
Simon Avatar asked Sep 07 '09 13:09

Simon


2 Answers

First set cell padding of your first column to 16 from left, so in view mode or edit mode, content will be shown using given padding.

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

Then handle CellPainting event and do these steps:

  1. Only paint first column and RowIndex should be >=0 to avoid rendering column header
  2. Paint your tree lines or whatever you want
  3. Cancel default painting using e.Handled = true

Here is the code:

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //Only paint first 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;
    }
}

and here is the screenshot:

enter image description here

like image 139
Reza Aghaei Avatar answered Oct 06 '22 03:10

Reza Aghaei


I solved a similar problem by creating a custom cell type, and shrinking the editing control as Bryan described. It's not terribly difficult, and it's the only way I'm aware of to keep the editing control from drawing on top of everything.

Something like this ought to work for you:

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;
        }
    }
}
like image 36
Andrew Watt Avatar answered Oct 06 '22 02:10

Andrew Watt