我有一个自定义 UserControl,其属性名为 ParentNode,类型为 OptionsNode,它继承了 TreeNode。我的控件包含一个 TreeView,其中许多节点在设计时显示。ParentNode 属性应该让用户在 TreeView 中选择一个节点,类似于从属性网格的下拉列表中选择组件的方式,然后下拉列表显示所有可用的组件。例如,任何表单的 AcceptButton 属性都会显示一个下拉列表,其中包含表单上的所有按钮可供选择。
为了在属性网格中获得这种行为,我为 OptionsNode 类编写了一个自定义 UITypeEditor。这告诉属性网格显示一个下拉列表,并在此下拉列表中添加一个 ListBox,其中填充了 TreeView 中所有节点的列表。这很好用,用户可以下拉“属性”并通过单击它来选择一个节点。
现在,在做了更多工作之后,我实现了一个自定义的 ControlDesigner,以及一个 ActionList,有时也称为 Smart Tag 面板。我说的是当您单击某些控件右上角的 [>] 按钮时弹出的带有通用属性/设计器方法的小弹出窗口(例如,TabControl 允许您从那里添加/删除标签页)。
我以前都这样做过,而且工作正常。现在的问题是我想在 ActionList 面板上显示相同的 ParentNode 属性。因此,DesignerActionList 类有一个“代理属性”,它将属性值从 ActionList 传递到控件,反之亦然,正如文档和本文中所述:http: //msdn.microsoft.com/ zh-CN/杂志/cc163758.aspx#S3
代码:
Friend Class OptionsPanelActionList
Inherits DesignerActionList
Public Sub New(ByVal host As OptionsPanel)
MyBase.New(host)
End Sub
Public Property ParentNode As OptionsNode
Get
Return Me.Host.ParentNode
End Get
Set(value As OptionsNode)
Me.SetProperty("ParentNode", value)
Me.DesignerActionService.Refresh(Me.Host)
End Set
End Property
Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection
Dim items As New DesignerActionItemCollection
items.Add(New DesignerActionPropertyItem("ParentNode", "Parent node:", String.Empty, "Gets or sets the parent node."))
Return items
End Function
End Class
但是,这不起作用。ActionList 只是在智能标签面板中显示一个 TextBox 而不是我的自定义 UITypeEditor。
我在之前链接的文章(http://msdn.microsoft.com/en-us/magazine/cc163758.aspx#S3)中阅读了更多内容,他专门研究了这个问题。他的时钟控件有一个带有 FaceEditor UITypeEditor 的 Face 属性,允许人们通过下拉菜单以图形方式选择时钟面(数字、模拟或两者)。
他的解决方案是简单地用 Editor 属性装饰代理属性,与原始 Face 属性相同。
好的,所以我尝试了:
<Editor(GetType(Editors.OptionsNodeEditor), GetType(UITypeEditor))> _
Public Property ParentNode As OptionsNode
Get
Return Me.Host.ParentNode
End Get
Set(value As OptionsNode)
Me.SetProperty("ParentNode", value)
Me.DesignerActionService.Refresh(Me.Host)
End Set
End Property
当我打开动作列表窗口时,它显示的是下拉样式而不是文本框。伟大的!但是,当我尝试打开下拉列表时,我收到一个错误:“使用下拉列表时出错:无法将'OptionsPanelActionList'类型的对象转换为'OptionsPanel'”
我不明白这个错误。它似乎试图将 OptionsPanelActionList 对象转换为 OptionsPanel。OptionsPanel 是我正在设计的控件(OptionsPanelActionList 是 OptionsPanelDesigner 中的 ActionList,是 OptionsPanel 控件的设计器),但我看不出它与这里有什么关系。我没有在任何地方进行投射,但显然代码在某处幕后执行此操作。
我错过了什么?为什么我的编辑器在尝试使用自定义 UITypeEditor 时会抛出错误,而文章指出它应该可以工作?
谢谢!