У меня есть пользовательский UserControl со свойством ParentNode типа OptionsNode, которое наследует TreeNode. Мой элемент управления содержит TreeView, в котором многие из этих узлов отображаются во время разработки. Предполагается, что свойство ParentNode позволяет пользователю выбрать один из узлов в TreeView, подобно тому, как можно выбрать компоненты из раскрывающегося списка в сетке свойств, затем в раскрывающемся списке отображаются все доступные компоненты. Например, свойство AcceptButton любой формы отображает раскрывающийся список со всеми кнопками в форме на выбор.
Чтобы получить такое поведение в сетке свойств, я написал пользовательский UITypeEditor для класса OptionsNode. Это говорит сетке свойств для отображения выпадающего списка, и в этом раскрывающемся списке я добавляю ListBox, который заполнен списком всех узлов в TreeView. Это прекрасно работает, пользователь может раскрыть «свойство» и выбрать узел, просто щелкнув по нему.
Теперь, после некоторой дополнительной работы, я реализовал собственный ControlDesigner, а также ActionList, иногда называемый панелью Smart Tag. Я говорю о небольшом всплывающем окне с общими свойствами / дизайнерских методах, которое появляется, когда вы нажимаете кнопку [>] в правом верхнем углу некоторых элементов управления (например, TabControl позволяет вам добавлять / удалять вкладки оттуда).
Я все делал это раньше, и он работает нормально. Проблема в том, что я хочу показать это же свойство ParentNode на панели ActionList. Итак, класс DesignerActionList имеет «свойство proxy», которое проходит через значение свойства из ActionList в элемент управления и наоборот, точно так же, как описано в документации, а также в этой статье: http://msdn.microsoft.com/en-us/magazine/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), и он специально решает эту проблему. Его элемент управления Clock имеет свойство Face с FaceEditor UITypeEditor, который позволяет людям графически выбирать циферблат часов (цифровой, аналоговый или оба) через раскрывающийся список.
Его решение состоит в том, чтобы просто декорировать свойство proxy с помощью атрибута 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
Когда я открываю окно списка действий, вместо TextBox отображается стиль выпадающего списка. Большой! Но как только я пытаюсь открыть выпадающий список, я получаю сообщение об ошибке:
«Ошибка использования раскрывающегося списка: невозможно привести объект типа« OptionsPanelActionList »к типу« OptionsPanel »»
Я не понимаю эту ошибку. Кажется, он пытается привести объект OptionsPanelActionList к OptionsPanel. OptionsPanel - это элемент управления, который я разрабатываю (OptionsPanelActionList - это ActionList в OptionsPanelDesigner, конструкторе для элемента управления OptionsPanel), но я не вижу, насколько он здесь уместен. Я нигде не кастую, но, видимо, код делает это где-то за кулисами.
Чего мне не хватает? Почему мой редактор выдает ошибки при попытке использовать пользовательский UITypeEditor, а в статье говорится, что он должен работать?
Спасибо!