在编辑DataGridView单元格时,如何绘制边框? [英] How do you draw a border around a DataGridView cell while it's being edited?

查看:1463
本文介绍了在编辑DataGridView单元格时,如何绘制边框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在编辑 c> DataGridView 单元格时绘制一个红色边框。

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 it's not being edited using this code:

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;
            }
        }
    }
}

其中产生此结果:

但是,当您编辑单元格时发生:

However, when you edit a cell this happens:

似乎 EditingControl 正在画我的大部分红色边框的顶部。不幸的是,我找不到一种方法来解决这个问题,所以我的红色边框将始终保持完整的显示。

It seems the EditingControl is drawing itself over the top of most of my red border. Unfortunately, I can't find a way to fix this so my red border will stay fully displayed at all times.

我该怎么做?

< br>
以下是我迄今为止所尝试的:

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

1. Handling the EditingControlShowing() event to manually re-draw the border like this:

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);
        }
    }
}

但这并没有画任何事情我尝试了一些这样的变化,但是他们都没有在这里留下任何东西。

But this didn't draw anything. I tried a few variations of this but all of them still drew nothing here.



2。然后我尝试处理 Paint()


2. I then tried to handle the Paint() event of the EditingControl like this:

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...");
}

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

But this event doesn't even fire. I later read somewhere that the EditingControl uses a normal TextBox, which doesn't fire the Paint() event because it's handled by Windows instead.



3。最后,我决定不要重新绘制另一个边框,而是决定
尝试通过调整 EditingControl 来调整大小
小于我的边框,希望边框会显示
左右,如下所示:


3. Finally, rather than trying to re-paint another border, I decided to try and hack around it by resizing the EditingControl to be smaller than my border in hopes the border would then show around it, like this:

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;
}

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

However, that just gave me this result:

所以 TextBox 在左边,但似乎还有另外一个
控制,它仍然阻挡我的红色边框。但是,我无法找到访问
的控件来调整它大小,所以这也不适用于我。

So the TextBox did move over to the Left, but it seems there is another control underneath it that is still blocking my red border. However, I can't find anyway to get access to that control to resize it so this didn't work for me either.



4。我还尝试使用#1以上的代码重新绘制边框在 Resize()事件,但仍然没有。虽然,使用 dataGridView1.EditingControl.BackColor = Color.Red; 做了工作,所以我可以在这里格式化控件的一些部分,但似乎试图画一个边框不是其中一个。


4. I also tried using the code from #1 above to re-draw the border in the Resize() event, but that still did nothing. Although, using dataGridView1.EditingControl.BackColor = Color.Red; did work so I can format some parts of the control here, but it seems trying to draw a border isn't one of them.

所有我想做的是在编辑时在单元格周围显示一个红色边框。你知道我能做什么吗?

All I want to do is keep a red border showing around the cell while it's being edited. Do you know how I can do this?

推荐答案

可以使用一些设置和绘制单元格的特定部分来完成。这样做:

It can be done using some settings and painting specific parts of cell. To so so:

首先,将 CellBorderStyle 设置为提高沉没在设计师或简单的形式加载代码:

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. 仅绘制网格内容单元格而不是ColumnHeader单元格或RowHeader

  2. 绘制所选单元格时,首先使用e.Paint(...)绘制除边框外的所有零件);然后绘制边框

  3. 设置e.Handled = true以防止默认绘画

  4. 绘制未选择的单元格时,首先使用e.Paint(...)

  5. 使用网格背景颜色绘制第一列单元格的第一行和第一列单元格的顶部边框

  6. 使用网格线颜色绘制最后一列的单元格的最后一行和右边框的单元格的底部边框

  7. 绘制非最后一行单元格的最后一行和右边框的单元格的底部边框列使用网格背景颜色

  8. 使用网格线颜色
    绘制非最后一列的单元格的非第一行和左边框的顶部边框单元9.Set e.Handled = true以防止默认绘画

  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

这是结果的截图,选择

这里是结果的截图,当编辑单元格

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;
            }
        }
    }
}

这篇关于在编辑DataGridView单元格时,如何绘制边框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆