如何使自定义DataGridViewComboBox仅依赖于其DataGridViewComboBoxColumn?

时间:2015-07-16 23:21:37

标签: .net winforms events datagridviewcolumn datagridviewcombobox

热门方式(12) 对于 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)
    }
}

1 个答案:

答案 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,因为一次只有一个可以有焦点。

如果你能更好地处理装饰器中的所有绘画代码。从事件中,它始终可以通过DataGridViewsender来回到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>

如果您愿意,还可以在注册时提供个人代表在绘画事件中进行调用。然后你必须保留这些列表,可能在字典中..