热门方式(1,2) 对于 DataGridViewComboBox 中项目的自定义绘制,是处理事件DataGridView1。 EditingControlShowing 并在那里设置DrawItem事件处理程序:
private void dataGridView1_EditingControlShowing(
object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
您会看到错误:它使用控制级事件来处理列的工作。但是,如果我有50多个datagridviews怎么办?应该按照列实例处理自定义组合框的绘制,保持控制级别不变。
下面是每列处理的最小实现。我唯一的问题是OnDrawItem()
方法没有被调用。我错过了什么? (您可以看到来自相同类的紫红色背景覆盖正在起作用。)
(要重现,只需将以下内容粘贴到类文件中,然后将 DataGridViewCustomPaintComboBoxColumn 类型的列添加到 DataGridView1 。)
public class DataGridViewCustomPaintComboBoxColumn : DataGridViewComboBoxColumn
{
public DataGridViewCustomPaintComboBoxColumn()
{
base.New();
CellTemplate = new DataGridViewCustomPaintComboBoxCell();
}
}
public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{
public override Type EditType {
get { return typeof(DataGridViewCustomPaintComboBoxEditingControl); }
}
protected override void Paint(...)
{
//painting stuff for incative cells here - works well
}
}
public class DataGridViewCustomPaintComboBoxEditingControl : DataGridViewComboBoxEditingControl
{
public override Color BackColor { // property override only for testing
get { return Color.Fuchsia; } // test value works as expected
set { base.BackColor = value; }
}
protected override void OnPaint(PaintEventArgs e) // never called - why?
{
base.OnPaint(e)
}
protected override void OnDrawItem(DrawItemEventArgs e) // never called - why?
{
base.OnDrawItem(e)
}
}
答案 0 :(得分:3)
我遇到的唯一问题是没有调用OnDrawItem()方法。我错过了什么?
您在焦点DataGridViewComboBoxCell
内看到的内容几乎是真实的' ComboBox
并且您需要引用它才能挂钩DrawItem
事件! (您可以查看DGV的Controls集合,看看当ComboBoxCell具有焦点时还有一个。DataGridViewComboBoxEditingControl
直接来自ComboBox
)
注意:开箱即用CombBox
的一个区别是默认设置为DrawMode = OwnerDrawVariable
。如果您想用自己创建的内容替换它,请不要忘记在代码中设置它!
看起来这就是你错过的东西!
如果您可以创建自己的DataGridViewComboBoxEditingControl
并将其显示在您的DGV中,则可以全部设置。
我经常使用的替代模型是一种“装饰器”,它为您注册的所有列实现自定义绘图。
DgvCombBoxPainter.Register(DataGridView dgv, stringOrInt columnNameOrIndex..)
在注册功能中,它会挂钩到必要的DGV方法,EditingControlShowing
来获取你看到的ComboBox
,当DGV有焦点而CellPainting
用于另一个时例。
装饰器可以是静态的,对于您已注册的所有列只需要一个ComboBox
,因为一次只有一个可以有焦点。
如果你能更好地处理装饰器中的所有绘画代码。从事件中,它始终可以通过DataGridView
和sender
来回到DataGridViewCellPaintingEventArgs
。属性通过ComboBox
参数..
您甚至可以将当前单元格的引用放入Tag
参考theBoxCell.Tag = dataGridView1.CurrentCell;
:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:function name="fetchXMLAttribute">
abcd
</xsl:function>
<xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes" encoding="utf-8" />
<xsl:template match="/*">
<html>
<body>
<div>
<xsl:attribute name="xmlAttribute">
<xsl:value-of select="fetchXMLAttribute()"/>
</xsl:attribute>
</div>
</body>
</html>
</xsl:template>
如果您愿意,还可以在注册时提供个人代表在绘画事件中进行调用。然后你必须保留这些列表,可能在字典中..