C# 为什么ListView的OnDrawItem事件不影响设计时环境?
如果我创建一个类并使它从一个列表视图中派生,就像这样C# 为什么ListView的OnDrawItem事件不影响设计时环境?,c#,winforms,listview,windows-forms-designer,design-time,C#,Winforms,Listview,Windows Forms Designer,Design Time,如果我创建一个类并使它从一个列表视图中派生,就像这样 class MyListView : ListView { public MyListView() : base() { DoubleBuffered = true; OwnerDraw = true; Cursor = Cursors.Hand; Scrollable = false; } protected override void OnD
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
。另一方面,当我运行我的应用程序时,我完全看到了我所期望的,并且没有列出任何项目
为什么这会影响运行时而不是设计时绘制
答案
ListViewDesigner
shadowsOwnerDraw
控件的属性,如Visible
或Enabled
属性。所以它只在运行时工作,更改它不会影响设计时
旁注
如果查看ListViewDesigner
的源代码,您将看到以下属性:
private bool OwnerDraw
{
get { return (bool) base.ShadowProperties["OwnerDraw"]; }
set { base.ShadowProperties["OwnerDraw"] = value; }
}
[Designer(typeof(ControlDesigner))]
public class MyListView : ListView
在PreFilterProperties
中,您将看到设计器将原始属性替换为以下属性:
PropertyDescriptor oldPropertyDescriptor = (PropertyDescriptor) properties["OwnerDraw"];
if (oldPropertyDescriptor != null)
{
properties["OwnerDraw"] = TypeDescriptor.CreateProperty(typeof(ListViewDesigner),
oldPropertyDescriptor, new Attribute[0]);
}
因此,无论您使用什么视图
,它都会执行默认的绘制,而不管您在OnDrawItem
中有什么。这是因为它在设计时不使用OwnerDraw
属性。设计师给它加上阴影。这与您在启用
或可见
属性中看到的行为相同
在运行时启用所有者绘制的变通方法
作为一种解决方法,您可以为派生控件注册不同的设计器。这样,OwnerDraw
属性将作为普通属性工作:
private bool OwnerDraw
{
get { return (bool) base.ShadowProperties["OwnerDraw"]; }
set { base.ShadowProperties["OwnerDraw"] = value; }
}
[Designer(typeof(ControlDesigner))]
public class MyListView : ListView
警告:请记住,为控件注册新设计器将丢失当前的ListViewDesigner
功能,如设计器谓词或智能标记(操作列表)窗口或列大小选项。如果您需要这些功能,您可以通过查看ListViewDesigner
源代码在自定义设计器中实现这些功能。。。。好吧,我将代码粘贴到一个新的类文件中,然后打开我的表单,单击工具箱并将其拖到表单上。我在表单上选择新对象,并将LargeImageList
更改为我的imagelist,编辑项目以包括一个带有imagelist中图像的项目,它使用LargeIcon
的默认视图。它在设计时显示的项目很好,但运行它时没有显示任何内容。。。你是如何让它工作的,这让我很惊讶。不设置视图属性是一个相当大的错误,在你自定义绘图时非常重要。现在,您只看到它绘制标签,而不是自定义绘制。猜测:不要使用Load事件来更改属性,这很笨拙。我还使用以下代码进行了测试:this.View=System.Windows.Forms.View.Details;this.OwnerDraw=true;本条第2栏添加(“X”);本条。添加(“1”);本条。添加(“2”)“代码>但没什么变化。@汉帕桑我不明白你的逻辑。你的印象是,我在Load
事件中做了一些事情,而我的印象是我没有。在我的代码中,我只有构造函数的代码,没有任何Load
事件。视图
属性已由基类设置。我真的不知道你的评论是朝什么方向发展的。@RezaAghaei你是想把视图设置成细节还是别的什么?因为默认值应该是LargeIcon。是否可以在设计期间以不同的方式显示这些更改?哪些更改?例如,我从ListViewDesigner
中添加了一些代码,我相信这些代码描述了原因。“有什么变化?”我希望在设计时看到自定义绘制的listview。没有办法看到他们吗?我记得在过去,如果我对PAINT事件做了一些事情,或者它是WM_PAINT消息的子类,以自定义绘制控件。它显示了我在设计时所做的所有更改。例如,我可以改变一种颜色作为道具,它将反映在设计时的形式。我测试了它,它的工作。我会加上它作为一个注释来回答。