我目前正在使用代码为选定的单元格创建边框。虽然我怀疑我是如何实现它的,但我遇到了一些视觉问题。对于我的应用程序,我有一个动态数量的选项卡,每个选项卡都有自己的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);
}
}
}
可悲的是,我仍然可以在切换标签的地方使用它,所选标签中的选定单元格可视地显示选定单元格的上一个标签。
我还发现我可以用一个网格重新创建问题。当我单击列标题然后按行排序行(默认功能)时,我注意到所选单元格保持不变。
视觉效果。如果我有以下列作为
当我点击订购我想要的列
时,我选择了值为3的单元格当我改变选择哪个单元格时,我会得到正确的
顺序我怀疑这个问题与我不了解的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内容。这是从第一列为空白的网格中获取的,在选择具有不同大小的不同选项卡中的单元格之后。可以看出,顶部的选定单元格具有预期的边框,但内部不是空白,而是另一个网格的图像。
对于同一网格内的问题,这里有一些额外的图片:
答案 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获得了大部分代码。
感到惊讶的是,当有关于制作边框或只是修改选定单元格的任何内容的讨论时,我没有看到这种联系。