为什么 ListView 的 OnDrawItem 事件不影响设计时环境?

Why does OnDrawItem event for a ListView not affect the Design-time environment?

如果我创建一个 class 并使它像这样从 ListView 派生...

class MyListView : ListView
{
    public MyListView() : base()
    {
        DoubleBuffered = true;
        OwnerDraw = true;
        Cursor = Cursors.Hand;
        Scrollable = false;
    }

    protected override void OnDrawItem(DrawListViewItemEventArgs e)
    {
        //base.OnDrawItem(e);
    }
}

然后我打开 windows 表单的设计视图并添加一个新的 MyListView 对象,然后添加一个项目并将其 link 添加到图像列表中。我可以看到 mylistview 对象中有一项。它对我在名为 lv 类型 MyListView 的表单上的对象没有影响。另一方面,当我 运行 我的应用程序时,我看到的正是我所期望的,并且没有列出任何项目。

为什么这种效果会 运行 时间而不是设计时绘画?

答案

ListViewDesigner 阴影 OwnerDraw 属性 像 VisibleEnabled 属性 的控制。所以它只在 运行 时有效,更改它不会影响设计时。

旁注

如果你看一下 ListViewDesigner 的源代码,你会看到这个 属性:

private bool OwnerDraw
{
    get { return (bool) base.ShadowProperties["OwnerDraw"]; }
    set { base.ShadowProperties["OwnerDraw"] = value; }
}

而在 PreFilterProperties 中,您会看到设计师将原来的 属性 替换成了这个:

PropertyDescriptor oldPropertyDescriptor = (PropertyDescriptor) properties["OwnerDraw"];
if (oldPropertyDescriptor != null)
{
    properties["OwnerDraw"] = TypeDescriptor.CreateProperty(typeof(ListViewDesigner), 
        oldPropertyDescriptor, new Attribute[0]);
}

因此,无论您使用什么 View,它都会执行默认绘画,而不管您在 OnDrawItem 中有什么。这是因为它在设计时没有使用 OwnerDraw 属性。设计师对其进行了阴影处理。这与您在 EnabledVisible 属性.

中看到的行为相同

在运行时间

启用所有者绘制的解决方法

作为变通方法,您可以为派生控件注册一个不同的 Designer。这样 OwnerDraw 属性 将像正常的 属性:

[Designer(typeof(ControlDesigner))]
public class MyListView : ListView

警告:请记住,通过为控件注册新的设计器,您将失去当前的 ListViewDesigner 功能,例如它的设计器动词或智能标记 (操作列表)window 或列大小选项。如果您需要这些功能,您可以通过查看 ListViewDesigner 源代码在自定义设计器中实现这些功能。