5

コントロールのコレクションを表すプロパティをコンポーネントに追加し、コレクションに属するコントロールを簡単に選択できるコレクションエディターを用意したいと思います。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を取得し、コントロールを追加および削除でき、コレクションがシリアル化されます。

問題は、新しいコントロールを追加したくないということです。フォームで使用可能な他のコントロールから複数のコントロールを選択したいのです。これを行う簡単で標準的な方法はありますか、それとも独自のコレクションエディターを作成してコントロールコレクションを実行する必要がありますか?

コレクションエディター(UITypeEditors)やその他のデザイン時のトピックに関する資料はたくさんありますが、この正確な動作を示すリンクを見つけることができなかったので、助けていただければ幸いです。

4

1 に答える 1

5

さて、その間に私は昼食をとり、自分でエディターを書きました。そんなに大変な努力ではありませんでした。それが役に立ったら、私は共有してうれしいです。

編集:ソリューションの概要

フォームにあるすべてのコントロールをツリービューに再帰的に一覧表示するエディター(スクリーンショットを参照)を作成しました。コントロールに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ファイルに入れました。こちらからダウンロードしてください

前に述べたように、これは内部使用のみを目的とした迅速で汚いソリューションでした。それでも、改善のための提案をいただければ幸いです。

于 2009-09-03T14:23:00.863 に答える