为什么 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
属性 像 Visible
或 Enabled
属性 的控制。所以它只在 运行 时有效,更改它不会影响设计时。
旁注
如果你看一下 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
属性。设计师对其进行了阴影处理。这与您在 Enabled
或 Visible
属性.
中看到的行为相同
在运行时间
启用所有者绘制的解决方法
作为变通方法,您可以为派生控件注册一个不同的 Designer
。这样 OwnerDraw
属性 将像正常的 属性:
[Designer(typeof(ControlDesigner))]
public class MyListView : ListView
警告:请记住,通过为控件注册新的设计器,您将失去当前的 ListViewDesigner
功能,例如它的设计器动词或智能标记 (操作列表)window 或列大小选项。如果您需要这些功能,您可以通过查看 ListViewDesigner
源代码在自定义设计器中实现这些功能。
如果我创建一个 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
属性 像 Visible
或 Enabled
属性 的控制。所以它只在 运行 时有效,更改它不会影响设计时。
旁注
如果你看一下 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
属性。设计师对其进行了阴影处理。这与您在 Enabled
或 Visible
属性.
在运行时间
启用所有者绘制的解决方法作为变通方法,您可以为派生控件注册一个不同的 Designer
。这样 OwnerDraw
属性 将像正常的 属性:
[Designer(typeof(ControlDesigner))]
public class MyListView : ListView
警告:请记住,通过为控件注册新的设计器,您将失去当前的 ListViewDesigner
功能,例如它的设计器动词或智能标记 (操作列表)window 或列大小选项。如果您需要这些功能,您可以通过查看 ListViewDesigner
源代码在自定义设计器中实现这些功能。