【问题标题】:Why does OnDrawItem event for a ListView not affect the Design-time environment?为什么 ListView 的 OnDrawItem 事件不会影响设计时环境?
【发布时间】:2016-10-30 22:20:37
【问题描述】:

如果我创建一个类并使其从这样的 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 对象,然后添加一个项目并将其链接到图像列表。我可以看到 mylistview 对象中有一项。它对我在名为lv、类型为MyListView 的表单上的对象没有影响。另一方面,当我运行我的应用程序时,我看到的正是我所期望的,并且没有列出任何项目。

为什么这会影响运行时而不是设计时绘制?

【问题讨论】:

  • 嗯...好吧,我将代码粘贴到一个新的类文件中,然后打开我的表单并单击工具箱并将其拖到表单上。我选择表单上的新对象并将LargeImageList 更改为我的图像列表并编辑项目以包含一个带有图像列表中图像的项目,它使用LargeIcon 的默认View。它在设计时显示该项目很好,但运行它并没有显示任何内容......你如何让它工作对我来说是惊人的。
  • 不设置 View 属性是一个很大的错误,在自定义绘图时很重要。现在你只是看到它绘制标签,这不是自定义绘制的。猜测:不要使用 Load 事件来更改属性,那是 gauche
  • 我也用这段代码测试过:this.View = System.Windows.Forms.View.Details; this.OwnerDraw = true; this.Columns.Add("X"); this.Items.Add("1"); this.Items.Add("2"); 但没有任何改变。
  • @HansPassant 我不明白你的逻辑。您的印象是我在 Load 事件中做某事,而我的印象是我没有。在我拥有的代码中,我只有构造函数的代码,没有任何 Load 事件。 View 属性已由基类设置。我真的很困惑你的评论的方向。
  • @RezaAghaei 您是否尝试将视图设置为详细信息或其他内容?因为默认应该是 LargeIcon。

标签: c# winforms listview windows-forms-designer design-time


【解决方案1】:

答案

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 功能,例如其设计器动词或其智能标记(操作列表)窗口或列大小选项。如果您需要这些功能,您可以通过查看ListViewDesigner 源代码在自定义设计器中实现这些功能。

【讨论】:

  • 是否可以在设计时以不同的方式显示这些更改?
  • 有什么变化?例如,如何?
  • 我添加了一些来自ListViewDesigner 的代码,我相信这描述了原因。
  • “有什么变化?”,我想在设计时看到我自定义绘制的列表视图。有没有办法看到他们?我记得过去如果我对 PAINT 事件做了一些事情,或者它可能是 WM_PAINT 消息的子类以自定义绘制控件。它显示了我在设计时所做的所有更改。例如,我可以将颜色更改为道具,它会在设计时反映在表单中。
  • 我测试了它并且它有效。我会将其添加为答案中的注释。
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 2013-06-12
  • 2021-04-06
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
相关资源
最近更新 更多