如何绘制 DataGridViewComboBox 列中的非活动行?
How to paint inactive rows in DataGridViewComboBox column?
我可以easily paint items in DataGridViewComboBox dropdown list。但是我想不通如何在同一列中绘制非活动单元格。
我看过、研究过并尝试过很多 classical ComboBox, but I don't understand all aspects of DataGridViewComboBox 的例子。
目前我有 DataGridViewCustomPaintComboBox class 来自 DataGridViewComboBox。提供的最小覆盖集是多少?你能给我指出正确的方向吗?
更新:
自定义绘图 DataGridViewComboBox
有点复杂。实际上它由四个不同的绘图案例组成:
对于未聚焦的单元格,您需要编写 CellPainting
事件代码:
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// drawstuff nr 1: draw the unfocused cell
}
当单元格获得焦点时,将创建并显示实际的 DataGridViewComboBoxEditingControl
(它是 ComboBox
的直接后代)。
您需要获取它的句柄(在 EditingControlShowing
事件中),然后应该在其 DrawItem
事件中编写另外三个案例:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
{
// drawstuff 2: draw the undropped top portion
}
else
{
if ((e.State & DrawItemState.Selected) != DrawItemState.None
{
// drawstuff 3: draw a selected item
}
else
{
// drawstuff 4: draw an unselected item
}
}
}
关于各种油漆代码的一些注意事项:
drawstuff 1:这里画完文字后要画一个箭头。为此最好使用 ComboBoxRenderer.DrawDropDownButton
方法。您将需要知道位置和大小,SystemInformation.VerticalScrollBarWidth
应该对此有所帮助。请注意 TextRenderer.DrawText
不仅可以让您使用漂亮的 TextFormatFlags
来帮助对齐,而且 Backcolor
!
drawstuff 2:请注意,不幸的是,ComboBox 没有选取其单元格的背景颜色。它仍然有助于设置它,因此您可以将其作为目标颜色。就像在下面的 darw 代码中一样,您将希望结合使用 e.Graphics.DrawXxx
调用和 TextRenderer.DrawText
。为了更容易引用它所属的 DGV 单元格,您可能希望在 EditingControlShowing
事件中设置它时将 CurrentCell
存储在引用 ComboBox
的 Tag
中。
drawstuff 3: 选中的项目可能有特殊的字体和背景颜色
drawstuff 4: 常规项目就是这样:相当常规..
下面的代码是我的答案的原始版本,仅涵盖案例3和4:
这里是一个简短的例子,向您展示如何绘制 DataGridViewComboBox
。请注意,我只展示了最低限度,并没有去画彩色方块..:[=35=]
我们首先定义对单元格的 class 级别引用:
ComboBox theBoxCell = null;
在EditingControlShowing
中我们设置引用,添加一个事件处理程序并将其设置为自绘模式:
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
最后我们添加绘制代码:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
string t = theBoxCell.Items[e.Index].ToString();
using (SolidBrush brush = new SolidBrush(
(e.State & DrawItemState.Selected) != DrawItemState.None ?
Color.LightCyan : Color.LightGray))
e.Graphics.FillRectangle(brush, e.Bounds);
e.DrawFocusRectangle();
e.Graphics.DrawString(t, Font, Brushes.DarkGoldenrod, e.Bounds.X + 6, e.Bounds.Y + 1);
}
我们也可以将 linq 中的绘制代码添加到事件连接中..
结果如下:
在没有焦点的情况下绘制非活动单元格所需的最小值似乎是CellTemplate
赋值和Paint()
覆盖:
public class DataGridViewCustomPaintComboBox : DataGridViewComboBoxColumn
{
public DataGridViewCustomPaintComboBox()
{
base.New();
CellTemplate = new DataGridViewCustomPaintComboBoxCell();
}
}
public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
// modify received arguments here
base.Paint(...); // paint default parts (see paintParts argument)
// add any custom painting here
}
}
我可以easily paint items in DataGridViewComboBox dropdown list。但是我想不通如何在同一列中绘制非活动单元格。
我看过、研究过并尝试过很多 classical ComboBox, but I don't understand all aspects of DataGridViewComboBox 的例子。
目前我有 DataGridViewCustomPaintComboBox class 来自 DataGridViewComboBox。提供的最小覆盖集是多少?你能给我指出正确的方向吗?
更新:
自定义绘图 DataGridViewComboBox
有点复杂。实际上它由四个不同的绘图案例组成:
对于未聚焦的单元格,您需要编写 CellPainting
事件代码:
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// drawstuff nr 1: draw the unfocused cell
}
当单元格获得焦点时,将创建并显示实际的 DataGridViewComboBoxEditingControl
(它是 ComboBox
的直接后代)。
您需要获取它的句柄(在 EditingControlShowing
事件中),然后应该在其 DrawItem
事件中编写另外三个案例:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
{
// drawstuff 2: draw the undropped top portion
}
else
{
if ((e.State & DrawItemState.Selected) != DrawItemState.None
{
// drawstuff 3: draw a selected item
}
else
{
// drawstuff 4: draw an unselected item
}
}
}
关于各种油漆代码的一些注意事项:
drawstuff 1:这里画完文字后要画一个箭头。为此最好使用
ComboBoxRenderer.DrawDropDownButton
方法。您将需要知道位置和大小,SystemInformation.VerticalScrollBarWidth
应该对此有所帮助。请注意TextRenderer.DrawText
不仅可以让您使用漂亮的TextFormatFlags
来帮助对齐,而且Backcolor
!drawstuff 2:请注意,不幸的是,ComboBox 没有选取其单元格的背景颜色。它仍然有助于设置它,因此您可以将其作为目标颜色。就像在下面的 darw 代码中一样,您将希望结合使用
e.Graphics.DrawXxx
调用和TextRenderer.DrawText
。为了更容易引用它所属的 DGV 单元格,您可能希望在EditingControlShowing
事件中设置它时将CurrentCell
存储在引用ComboBox
的Tag
中。drawstuff 3: 选中的项目可能有特殊的字体和背景颜色
drawstuff 4: 常规项目就是这样:相当常规..
下面的代码是我的答案的原始版本,仅涵盖案例3和4:
这里是一个简短的例子,向您展示如何绘制 DataGridViewComboBox
。请注意,我只展示了最低限度,并没有去画彩色方块..:[=35=]
我们首先定义对单元格的 class 级别引用:
ComboBox theBoxCell = null;
在EditingControlShowing
中我们设置引用,添加一个事件处理程序并将其设置为自绘模式:
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
最后我们添加绘制代码:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
string t = theBoxCell.Items[e.Index].ToString();
using (SolidBrush brush = new SolidBrush(
(e.State & DrawItemState.Selected) != DrawItemState.None ?
Color.LightCyan : Color.LightGray))
e.Graphics.FillRectangle(brush, e.Bounds);
e.DrawFocusRectangle();
e.Graphics.DrawString(t, Font, Brushes.DarkGoldenrod, e.Bounds.X + 6, e.Bounds.Y + 1);
}
我们也可以将 linq 中的绘制代码添加到事件连接中..
结果如下:
在没有焦点的情况下绘制非活动单元格所需的最小值似乎是CellTemplate
赋值和Paint()
覆盖:
public class DataGridViewCustomPaintComboBox : DataGridViewComboBoxColumn
{
public DataGridViewCustomPaintComboBox()
{
base.New();
CellTemplate = new DataGridViewCustomPaintComboBoxCell();
}
}
public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
// modify received arguments here
base.Paint(...); // paint default parts (see paintParts argument)
// add any custom painting here
}
}