如何在编辑DataGridView单元格时绘制边框?

Cal*_*lat 10 .net c# datagridview winforms

我想DataGridView在编辑时在单元格周围绘制一个红色边框.

我设法在所选单元格周围绘制一个红色边框,而不是使用此代码编辑它:

private void Form1_Load(object sender, EventArgs e)
{
    this.Width = 650;
    this.Height = 250;
    dataGridView1.Left = 5;
    dataGridView1.Top = 5;
    dataGridView1.Width = 600;
    dataGridView1.Height = 175;

    DataTable dt = new DataTable("Test Table");
    dt.Columns.Add("Column 1");
    dt.Columns.Add("Column 2");
    dt.Columns.Add("Column 3");
    dt.Columns.Add("Column 4");
    dt.Columns.Add("Column 5");
    dt.Rows.Add(dt.NewRow());
    dt.Rows.Add(dt.NewRow());
    dt.Rows.Add(dt.NewRow());
    dt.Rows.Add(dt.NewRow());
    dt.Rows.Add(dt.NewRow());
    dataGridView1.DataSource = dt;

    dataGridView1.AllowUserToAddRows = false;
    dataGridView1.AllowUserToDeleteRows = false;
    dataGridView1.MultiSelect = false;
    dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
    dataGridView1.DefaultCellStyle.SelectionBackColor = Color.White;
    dataGridView1.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.dataGridView1_CellPainting);
    dataGridView1.EditingControlShowing += new System.Windows.Forms.DataGridViewEditingControlShowingEventHandler(this.dataGridView1_EditingControlShowing);
}

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex != -1 && e.RowIndex != -1 && dataGridView1[e.ColumnIndex, e.RowIndex].Selected)
    {
        using (Brush borderBrush = new SolidBrush(Color.Red))
        {
            using (Pen borderPen = new Pen(borderBrush, 2))
            {
                Rectangle rectDimensions = e.CellBounds;
                rectDimensions.Width -= 2;
                rectDimensions.Height -= 2;
                rectDimensions.X = rectDimensions.Left + 1;
                rectDimensions.Y = rectDimensions.Top + 1;

                e.Graphics.DrawRectangle(borderPen, rectDimensions);

                e.Handled = true;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产生这个结果:

此搜索

但是,当您编辑单元格时会发生这种情况:

镜像2

看起来它EditingControl正在我的大部分红色边界上方.不幸的是,我找不到解决方法,所以我的红色边框将始终保持完全显示.

我怎样才能做到这一点???



这是我到目前为止所尝试的:

1.处理EditingControlShowing()事件以手动重新绘制边框,如下所示:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    Graphics gfx = e.Control.CreateGraphics();

    using (Brush borderBrush = new SolidBrush(Color.Red))
    {
        using (Pen borderPen = new Pen(borderBrush, 2))
        {
            Rectangle rectDimensions = e.Control.ClientRectangle;
            rectDimensions.Width -= 2;
            rectDimensions.Height -= 2;
            rectDimensions.X = rectDimensions.Left + 1;
            rectDimensions.Y = rectDimensions.Top + 1;

            gfx.DrawRectangle(borderPen, rectDimensions);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但这没有任何吸引力.我尝试了一些这方面的变化,但所有这些仍然没有在这里画.


2.我又试图处理Paint()的事件EditingControl 是这样的:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    e.Control.Paint -= new PaintEventHandler(dataGridView1_EditingControl_Paint);
    e.Control.Paint += new PaintEventHandler(dataGridView1_EditingControl_Paint);
}

void dataGridView1_EditingControl_Paint(object sender, PaintEventArgs e)
{
    MessageBox.Show("Starting EditingControl Paint() Event...");
}
Run Code Online (Sandbox Code Playgroud)

但是这个事件甚至没有发生.我后来在某处读到了 EditingControl使用普通的TextBox,它不会触发 Paint()事件,因为它是由Windows处理的.


3.最后,我没有尝试重新绘制另一个边框,而是决定尝试通过调整尺寸EditingControl小于边框来修复它,希望边框会显示在它周围,如下所示:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    e.Control.Resize -= new EventHandler(dataGridView1_EditingControl_Resize);
    e.Control.Resize += new EventHandler(dataGridView1_EditingControl_Resize);
}

void dataGridView1_EditingControl_Resize(object sender, EventArgs e)
{
    dataGridView1.EditingControl.Left = 20;
}
Run Code Online (Sandbox Code Playgroud)

但是,这只是给了我这个结果:

图像3

所以TextBox确实移到了左边,但似乎在它下面有另一个控制仍然阻挡我的红色边框.但是,无论如何我无法找到访问该控件来调整它的大小,所以这对我来说也不起作用.


4.我也尝试使用上面#1中的代码重新绘制Resize()事件中的边框,但这仍然没有做任何事情.虽然,使用dataGridView1.EditingControl.BackColor = Color.Red;确实有效,所以我可以在这里格式化控件的某些部分,但似乎试图绘制边框不是其中之一.

我想做的就是在编辑时在单元格周围显示一个红色边框.你知道我怎么做吗?

Rez*_*aei 8

可以使用一些设置和绘制单元格的特定部分来完成.如此:

首先,设置CellBorderStyleRaisedSunken在设计器中或简单地在表单中加载代码:

this.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.Raised;
Run Code Online (Sandbox Code Playgroud)

然后使用这些特定的有序规则绘制单元格

  1. 仅绘制网格内容单元格而不绘制ColumnHeader单元格或RowHeader
  2. 绘制选定单元格时,首先使用e.Paint(...)绘制除边框以外的所有零件; 然后自己画边框
  3. 设置e.Handled = true以防止默认绘画
  4. 绘制非选定单元格时,首先使用e.Paint(...)绘制除边框外的所有零件
  5. 使用网格背景颜色绘制第一列单元格的第一行和左边界单元格的顶部边框
  6. 使用网格线颜色绘制最后一行单元格的底部边框和最后一列单元格的右边框
  7. 使用网格背景颜色绘制非最后一列和非最后一列的单元格的右边界的单元格的底部边框
  8. 使用网格线颜色绘制非最后一列单元格的非第一行和左边框的顶部边框单元格.设置e.Handled = true以防止默认绘制

这是选择后的结果截图

在此输入图像描述

这是编辑单元格时的结果截图

在此输入图像描述

这是细胞绘制事件的代码:

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


NAS*_*SER 3

使用现有代码的最简单方法是将 设置为CellBorderStyleSunken,如下所示:

dataGridView1.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Sunken;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果您不喜欢凹陷,那么您可以通过AdjustCellBorderStyleDataGridViewAdvancedBorderStyle来实现此目的,在单元格焦点事件中更改/自定义单元格边框样式。另请参阅:如何:通过扩展 Windows 窗体 DataGridView 控件的行为和外观来自定义单元格和列

我希望它能帮助你。