さて、その間に私は昼食をとり、自分でエディターを書きました。そんなに大変な努力ではありませんでした。それが役に立ったら、私は共有してうれしいです。
編集:ソリューションの概要
フォームにあるすべてのコントロールをツリービューに再帰的に一覧表示するエディター(スクリーンショットを参照)を作成しました。コントロールにTextまたはImageプロパティが設定されている場合、テキスト/画像が表示されます。ユーザーは、チェックボックスを使用して複数のコントロールを選択し、リストをフィルタリングして特定のタイプのコントロールのみを表示することもできます。
(ただし、このエディターは内部使用のみを目的としているため、画像プロパティを一般的にチェックする必要はなく、いくつかのよく知られたコントロールタイプを処理するだけです。)
エディターフォームのコードは、実際にはUI専用であり、ツリーに入力し、事前に選択されたコントロールのリストにチェックを設定し、ユーザーが[OK]でフォームを閉じたときに選択されたコントロールのリストを返します。
次に、私がFormControlSelectionEditorと呼んだUITypeEditorを実装するクラスがあります。このクラスは、[Editor]属性を使用するためにエディターを使用するプロパティに割り当てられます。必要に応じてフォームの新しいインスタンスを作成し、それをモーダルダイアログとして表示するだけです。
次に、System.Collections.ObjectModel.ObservableCollection(Of Control)タイプのプロパティ自体があります。実行時にリストへの変更にも対応する必要があるため、ObservableCollectionを選択しましたが、他のリストもわずかな調整で同様に機能します。
私が発見したことの1つは、コントロールのリストのコピーを使用するようにプロパティとエディターを作成する必要があることです。つまり、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ファイルに入れました。こちらからダウンロードしてください。
前に述べたように、これは内部使用のみを目的とした迅速で汚いソリューションでした。それでも、改善のための提案をいただければ幸いです。