How do you draw a border around a DataGridView cell while it's being edited?

后端 未结 3 1186
野性不改
野性不改 2020-12-16 18:05

I would like to draw a red border around a DataGridView cell while it\'s being edited.

I\'ve managed to draw a red border around the selected cell while

相关标签:
3条回答
  • It can be done using some settings and painting specific parts of cell. To so so:

    First, set CellBorderStyle to Raised or Sunken in designer or simply in form load code:

    this.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.Raised;
    

    Then draw cells using these specific ordered rules:

    1. Draw only grid content cells not ColumnHeader cells nor RowHeader
    2. When drawing selected cells, first paint all parts except borders using e.Paint(...); then draw borders yourself
    3. Set e.Handled=true to prevent default painting
    4. When drawing non-selected cells, first paint all parts except borders using e.Paint(...)
    5. Draw top border of cells of first row and left border of cells of first column using grid background color
    6. Draw bottom border of cells of last row and right border of cells of last column using grid line color
    7. Draw bottom border of cells of non-last row and right border of cells of non-last column using grid background color
    8. Draw top border cells of non-first row and left border of cells of non-last column using grid line color 9.Set e.Handled=true to prevent default painting

    This is screenshot of result, after select

    and here is screenshot of result, when editing cell

    and here is the code of cell paint event:

    private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        //Draw only grid content cells not ColumnHeader cells nor RowHeader cells
        if (e.ColumnIndex > -1 & e.RowIndex > -1)
        {
            //Pen for left and top borders
            using (var backGroundPen = new Pen(e.CellStyle.BackColor, 1))
            //Pen for bottom and right borders
            using (var gridlinePen = new Pen(dataGridView1.GridColor, 1))
            //Pen for selected cell borders
            using (var selectedPen = new Pen(Color.Red, 1))
            {
                var topLeftPoint = new Point(e.CellBounds.Left, e.CellBounds.Top);
                var topRightPoint = new Point(e.CellBounds.Right - 1, e.CellBounds.Top);
                var bottomRightPoint = new Point(e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                var bottomleftPoint = new Point(e.CellBounds.Left, e.CellBounds.Bottom - 1);
    
                //Draw selected cells here
                if (this.dataGridView1[e.ColumnIndex, e.RowIndex].Selected)
                {
                    //Paint all parts except borders.
                    e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.Border);
    
                    //Draw selected cells border here
                    e.Graphics.DrawRectangle(selectedPen, new Rectangle(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Width - 1, e.CellBounds.Height - 1));
    
                    //Handled painting for this cell, Stop default rendering.
                    e.Handled = true;
                }
                //Draw non-selected cells here
                else
                {
                    //Paint all parts except borders.
                    e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.Border);
    
                    //Top border of first row cells should be in background color
                    if (e.RowIndex == 0)
                        e.Graphics.DrawLine(backGroundPen, topLeftPoint, topRightPoint);
    
                    //Left border of first column cells should be in background color
                    if (e.ColumnIndex == 0)
                        e.Graphics.DrawLine(backGroundPen, topLeftPoint, bottomleftPoint);
    
                    //Bottom border of last row cells should be in gridLine color
                    if (e.RowIndex == dataGridView1.RowCount - 1)
                        e.Graphics.DrawLine(gridlinePen, bottomRightPoint, bottomleftPoint);
                    else  //Bottom border of non-last row cells should be in background color
                        e.Graphics.DrawLine(backGroundPen, bottomRightPoint, bottomleftPoint);
    
                    //Right border of last column cells should be in gridLine color
                    if (e.ColumnIndex == dataGridView1.ColumnCount - 1)
                        e.Graphics.DrawLine(gridlinePen, bottomRightPoint, topRightPoint);
                    else //Right border of non-last column cells should be in background color
                        e.Graphics.DrawLine(backGroundPen, bottomRightPoint, topRightPoint);
    
                    //Top border of non-first row cells should be in gridLine color, and they should be drawn here after right border
                    if (e.RowIndex > 0)
                        e.Graphics.DrawLine(gridlinePen, topLeftPoint, topRightPoint);
    
                    //Left border of non-first column cells should be in gridLine color, and they should be drawn here after bottom border
                    if (e.ColumnIndex > 0)
                        e.Graphics.DrawLine(gridlinePen, topLeftPoint, bottomleftPoint);
    
                    //We handled painting for this cell, Stop default rendering.
                    e.Handled = true;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-16 18:31

    It seems like the EditingControl is hosted in a parent Panel, and if you set the Opaque style of that panel to true, then the border will be painted.

    E.g.

    void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
        var c = e.Control;
        var p = c.Parent;
        SetStyles(p, ControlStyles.Opaque, true);
    }
    
    private static void SetStyles(Control c, ControlStyles styles, bool value) {
        MethodInfo mi = typeof(Control).GetMethod("SetStyle", BindingFlags.NonPublic | BindingFlags.Instance);
        mi.Invoke(c, new Object[] { styles, value });
    }
    
    0 讨论(0)
  • 2020-12-16 18:34

    The most simple approach using your existing code is setting of the CellBorderStyle to Sunken as shown below:

    dataGridView1.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Sunken;
    

    If you don't like Sunken, then you can achieve this by AdjustCellBorderStyle and DataGridViewAdvancedBorderStyle, in cell focus event change/customize the cell border style. Also take a look at: How to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance.

    I hope it w'd help you.

    0 讨论(0)
提交回复
热议问题