我想添加一个表示组件控件集合的属性,并有一个集合编辑器,通过它我可以轻松选择属于集合的控件。 VS使用以下代码自动几乎我想要的东西:
Private _controls As New List(Of Control)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property SelectedControls() As List(Of Control)
Get
Return _controls
End Get
End Property
我得到默认的CollectionEditor,可以添加和删除控件,并且集合是序列化的。
问题是我不想添加 new 控件,我想从表单上的其他可用控件中选择多个控件。有没有简单/标准的方法来做到这一点,或者我是否必须编写自己的集合编辑器并运行控件集合?
虽然收藏编辑器(UITypeEditors)和其他设计时主题上有很多材料,但我找不到任何证明这种确切行为的链接,所以感谢任何帮助。
答案 0 :(得分:4)
好的,所以我平时吃午饭并自己写了编辑。没有这么大的努力。如果有帮助,我很乐意分享。
编辑:解决方案摘要
我写了一个编辑器(见截图),它以树形视图的形式递归列出了表单上的所有控件。如果控件设置了“文本”或“图像”属性,则会显示文本/图像。用户可以使用复选框选择多个控件,甚至可以过滤列表以仅显示某些类型的控件。
(但我必须承认,由于这个编辑器仅供内部使用,我没有费心去检查图像属性,我只是处理一些众所周知的控件类型。)
alt text http://i37.tinypic.com/154enpw.png
编辑器表单中的代码实际上仅用于UI,负责填充树,在预先选择的控件列表上设置检查,并在用户使用OK关闭表单时返回所选控件的列表。 / p>
接下来,我们有一个实现UITypeEditor的类,我称之为FormControlSelectionEditor。此类分配给我们要使用编辑器使用[Editor]属性的属性。它只需要在需要时创建表单的新实例并将其显示为模式对话框。
然后是属性本身,它们的类型为System.Collections.ObjectModel.ObservableCollection(Of Control)。我之所以选择ObservableCollection是因为我需要在运行时对列表的更改作出反应,但其他列表也可以通过微调进行。
我发现的一件事是我必须编写我的属性和编辑器,以便他们使用控件列表的副本。换句话说,UITypeEditor代码生成存储在属性中的列表的副本,并将其传递给编辑器表单(用于在打开表单时设置检查),当表单关闭时,我清除属性的支持列表,复制从编辑器返回的列表中的每个控件。我发现,否则我在.designer文件中遇到序列化问题。我不相信它必须这样;我认为这更可能是我的错误。
典型财产的代码:
Private WithEvents _insertButtons As New System.Collections.ObjectModel.ObservableCollection(Of Control)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
<Editor(GetType(Design.FormControlSelectionEditor), GetType(UITypeEditor))> _
Public Property InsertButtons() As System.Collections.ObjectModel.ObservableCollection(Of Control)
Get
Return _insertButtons
End Get
Set(ByVal value As System.Collections.ObjectModel.ObservableCollection(Of Control))
If value Is Nothing Then
RemoveInsertButtonEventHandlers(_insertButtons)
_insertButtons.Clear()
Else
' Copy the list items passed in into the internal list
For i As Integer = _insertButtons.Count - 1 To 0 Step -1
If Not value.Contains(_insertButtons.Item(i)) Then _insertButtons.RemoveAt(i)
Next
For Each ctl As Control In value
If Not _insertButtons.Contains(ctl) Then _insertButtons.Add(ctl)
Next
End If
End Set
End Property
Private Function ShouldSerializeInsertButtons() As Boolean
Return _insertButtons.Count > 0
End Function
Private Sub ResetInsertButtons()
InsertButtons = Nothing
End Sub
我把编辑器放到一个zip文件中; download it here
正如我之前提到的,这只是一个快速的&amp;脏的解决方案仅供内部使用。尽管如此,我还是对任何改进建议表示赞赏。