自动调整使用自定义绘画的 DataGridViewComboBoxCell
Autosize a DataGridViewComboBoxCell which uses custom painting
我的 DataGridView
上面有一个 DataGridViewComboBoxColumn
。这是我的自定义单元格绘制处理程序:
private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == 1 && e.RowIndex >= 0)
{
e.PaintBackground(e.CellBounds, true);
//e.PaintContent(e.CellBounds);
Graphics g = e.Graphics;
Color c = Color.Empty;
string s = "";
Brush br = SystemBrushes.WindowText;
Brush brBack;
Rectangle rDraw;
rDraw = e.CellBounds;
rDraw = Rectangle.FromLTRB(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Right, e.CellBounds.Bottom - 1);
brBack = Brushes.White;
Pen penGridlines = new Pen(dataGridView.GridColor);
g.DrawRectangle(penGridlines, rDraw);
g.FillRectangle(brBack, rDraw);
penGridlines.Dispose();
if (dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
ComboboxColourItem oColourItem = (ComboboxColourItem)dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
s = oColourItem.ToString();
c = oColourItem.Value;
}
int butSize = e.CellBounds.Height;
Rectangle rbut = new Rectangle(e.CellBounds.Right - butSize,
e.CellBounds.Top, butSize, butSize);
ComboBoxRenderer.DrawDropDownButton(e.Graphics, rbut,
System.Windows.Forms.VisualStyles.ComboBoxState.Normal);
if (c != Color.Empty)
{
SolidBrush b = new SolidBrush(c);
Rectangle r = new Rectangle(e.CellBounds.Left + 6,
e.CellBounds.Top + 5, 10, 10);
g.FillRectangle(b, r);
g.DrawRectangle(Pens.Black, r);
g.DrawString(s, Form.DefaultFont, Brushes.Black,
e.CellBounds.Left + 25, e.CellBounds.Top + 3);
b.Dispose();
}
e.Handled = true;
}
}
当我通过双击 DVG 的右侧编辑来自动调整填充列的大小时,会发生以下情况:
如何调整行为以便在自动调整大小时考虑组合下拉菜单?
谢谢。
当您双击列 header 分隔符使列自动调整大小时,它会使列宽等于最宽的单元格。自动调整大小模式下组合框单元格的宽度使用以下公式计算:
- 格式化值的宽度
- 组合框按钮的宽度
- 单元格样式填充
- 图标宽度错误
- 文本、按钮和图标周围有一些额外的填充
快速修复
在您的情况下,这些彩色矩形占用 space,但在计算单元格的自动大小时,不会计算它们的宽度和周围的 spaces。
作为一个简单的解决方案,您可以在列中添加一些填充。您可以在设计器中执行此操作,方法是编辑列并在 DefaultCellStyle
中为列设置填充。还可以使用您可以编写的代码,例如:
column.DefaultCellStyle.Padding = new Padding(16,0,16,0);
长期解决方案
如果列是可重复使用的列类型,我建议您创建自定义列类型。然后你可以在你的自定义单元格中封装绘画逻辑和计算大小以及一些其他功能。如果您决定创建自定义单元格,您会发现这些与问题相关的方法很有用:
我的 DataGridView
上面有一个 DataGridViewComboBoxColumn
。这是我的自定义单元格绘制处理程序:
private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == 1 && e.RowIndex >= 0)
{
e.PaintBackground(e.CellBounds, true);
//e.PaintContent(e.CellBounds);
Graphics g = e.Graphics;
Color c = Color.Empty;
string s = "";
Brush br = SystemBrushes.WindowText;
Brush brBack;
Rectangle rDraw;
rDraw = e.CellBounds;
rDraw = Rectangle.FromLTRB(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Right, e.CellBounds.Bottom - 1);
brBack = Brushes.White;
Pen penGridlines = new Pen(dataGridView.GridColor);
g.DrawRectangle(penGridlines, rDraw);
g.FillRectangle(brBack, rDraw);
penGridlines.Dispose();
if (dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
ComboboxColourItem oColourItem = (ComboboxColourItem)dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
s = oColourItem.ToString();
c = oColourItem.Value;
}
int butSize = e.CellBounds.Height;
Rectangle rbut = new Rectangle(e.CellBounds.Right - butSize,
e.CellBounds.Top, butSize, butSize);
ComboBoxRenderer.DrawDropDownButton(e.Graphics, rbut,
System.Windows.Forms.VisualStyles.ComboBoxState.Normal);
if (c != Color.Empty)
{
SolidBrush b = new SolidBrush(c);
Rectangle r = new Rectangle(e.CellBounds.Left + 6,
e.CellBounds.Top + 5, 10, 10);
g.FillRectangle(b, r);
g.DrawRectangle(Pens.Black, r);
g.DrawString(s, Form.DefaultFont, Brushes.Black,
e.CellBounds.Left + 25, e.CellBounds.Top + 3);
b.Dispose();
}
e.Handled = true;
}
}
当我通过双击 DVG 的右侧编辑来自动调整填充列的大小时,会发生以下情况:
如何调整行为以便在自动调整大小时考虑组合下拉菜单?
谢谢。
当您双击列 header 分隔符使列自动调整大小时,它会使列宽等于最宽的单元格。自动调整大小模式下组合框单元格的宽度使用以下公式计算:
- 格式化值的宽度
- 组合框按钮的宽度
- 单元格样式填充
- 图标宽度错误
- 文本、按钮和图标周围有一些额外的填充
快速修复
在您的情况下,这些彩色矩形占用 space,但在计算单元格的自动大小时,不会计算它们的宽度和周围的 spaces。
作为一个简单的解决方案,您可以在列中添加一些填充。您可以在设计器中执行此操作,方法是编辑列并在 DefaultCellStyle
中为列设置填充。还可以使用您可以编写的代码,例如:
column.DefaultCellStyle.Padding = new Padding(16,0,16,0);
长期解决方案
如果列是可重复使用的列类型,我建议您创建自定义列类型。然后你可以在你的自定义单元格中封装绘画逻辑和计算大小以及一些其他功能。如果您决定创建自定义单元格,您会发现这些与问题相关的方法很有用: