DataGridView选定的单元格边框显示错误的单元格

时间:2017-10-18 21:32:22

标签: c# datagridview

我目前正在使用代码为选定的单元格创建边框。虽然我怀疑我是如何实现它的,但我遇到了一些视觉问题。对于我的应用程序,我有一个动态数量的选项卡,每个选项卡都有自己的DataGridView,因此所有网格都使用以下事件:

    private void gridSelection_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        TabPage currentPage = tabs.SelectedTab;
        DataGridView currentGrid = currentPage.Controls[0] as DataGridView;
        if (currentGrid.Equals(sender))
        {
            if (e.ColumnIndex != -1 && e.RowIndex != -1 && currentGrid[e.ColumnIndex, e.RowIndex].Selected)
            {
                using (Pen borderPen = new Pen(Color.Black, 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;
                }

            }
        }
    }

我的问题来自更改标签。选定选项卡上的选定单元格仍显示上一个选项卡中的单元格。解决方法是用户只需选择一个新单元格,然后一切都恢复正常运行。 (我会展示一个视觉,但每个单元格都充满了我公司非常秘密的知识产权)。

从上面的代码中可以看出,我试图确保触发事件的唯一网格是当前正在向用户显示的网格。我甚至尝试使用tab_change事件阻止前一个网格触发事件:

    private void tabChange(object sender, EventArgs e)
    {
        TabPage currentPage = tabs.SelectedTab;
        DataGridView currentGrid = currentPage.Controls[0] as DataGridView;
        currentGrid.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(gridSelection_CellPainting);
        foreach (TabPage tab1 in tabs.TabPages)
        {
            if (!tab1.Equals(currentPage))
            {
                DataGridView otherGrid = operation.Controls[0] as DataGridView;
                otherGrid.CellPainting -= new System.Windows.Forms.DataGridViewCellPaintingEventHandler(gridSelection_CellPainting);
            }
        }
    }

可悲的是,我仍然可以在切换标签的地方使用它,所选标签中的选定单元格可视地显示选定单元格的上一个标签。

我还发现我可以用一个网格重新创建问题。当我单击列标题然后按行排序行(默认功能)时,我注意到所选单元格保持不变。

视觉效果。如果我有以下列作为

  • 1
  • 2
  • 3
  • 4

当我点击订购我想要的列

时,我选择了值为3的单元格
  • 4
  • 3
  • 3
  • 1

当我改变选择哪个单元格时,我会得到正确的

顺序
  • 4
  • 3
  • 2
  • 1

我怀疑这个问题与我不了解的DrawRectangle函数的细微差别有关。其他人看过这个或已经解决了吗?

由于

编辑:

更新,更清晰的代码。 Tabchange现在几乎是空的,它有一些我没有显示的代码,因为如果我发表评论它对我的问题没有影响。

对于细胞绘画:

    private void gridSelection_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        TabPage currentPage = tabs.SelectedTab;
        DataGridView currentGrid = currentPage.Controls[0] as DataGridView;
        if (e.ColumnIndex != -1 && e.RowIndex != -1 && currentGrid[e.ColumnIndex, e.RowIndex].Selected)
        {
            using (Pen borderPen = new Pen(Color.Black, 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;
            }

        }
    }

我需要保留currentGrid代码,因为我需要验证是否选中了单元格。我从预期的事件中得到的代码只被绑定到一个网格,这个网格可以被轻松调用,而不是一个与动态网格数量相关的事件。

编辑编辑:

Image of cell showing visual error

我添加了一个裁剪的图片以隐藏IP内容。这是从第一列为空白的网格中获取的,在选择具有不同大小的不同选项卡中的单元格之后。可以看出,顶部的选定单元格具有预期的边框,但内部不是空白,而是另一个网格的图像。

对于同一网格内的问题,这里有一些额外的图片:

Correct descending order

After column header clicked to be ascending order

After changing which cell is selected

1 个答案:

答案 0 :(得分:0)

经过一些挖掘和实验,在我看来,每当我使用图形绘制一个矩形时,矩形每次都被干净地绘制,但是单元格的内部就是从上一次绘制事件中剩下的任何内容。细胞。它不像是在进行单元格的默认绘制,然后在其上面绘制一个矩形。也就是说,我觉得我正在压倒正常的油漆事件,这会显示一个细胞及其价值。

这是有道理的,因为我重写默认行为以显示突出显示的单元格。在查看我的代码时,它所做的只是绘制一个矩形,并且应该注意到它没有改变所选单元格的颜色(默认为蓝色)。所以我的解决方案就是尝试在整个过程中重新创建单元格。

    private void gridSelection_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        TabPage currentPage = tabs.SelectedTab;
        DataGridView currentGrid = currentPage.Controls[0] as DataGridView;
        if (e.ColumnIndex != -1 && e.RowIndex != -1 && currentGrid[e.ColumnIndex, e.RowIndex].Selected)
        {
            using (Pen borderPen = new Pen(Color.Black, 2))
            {
                Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor);
                // Erase the cell.
                e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

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

                // Draw the text content of the cell, ignoring alignment.
                if (e.Value != null)
                {
                    Brush textColor = new SolidBrush(e.CellStyle.ForeColor);

                    e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                        textColor, e.CellBounds.X +1,
                        e.CellBounds.Y + 3, StringFormat.GenericDefault);
                }

                e.Handled = true;
            }

        }
    }

一个善良的眼睛仍然会看到它不是一个完美的娱乐,我将不得不更多地使用格式和对齐,但它是非常好的,不值得我的时间让它完美。

当然可以归功于它应有的位置,从MSDN获得了大部分代码。

感到惊讶的是,当有关于制作边框或只是修改选定单元格的任何内容的讨论时,我没有看到这种联系。