0

これは不可能であるか、少し間違っているかもしれませんが、WinForms には特定のオプションを入力する必要があるコンボ ボックスがあります。このプロジェクトでは約 10 種類のフォームを使用しており、すべて似ているがわずかに異なる機能を備えています。

ここで、オプションの簡単な辞書を作成し、値に Enum を渡しました。コードが重複していることに気付き、統合したいと考えています。オプションセットは日付順と名前順ですが、他に 1 つまたは 2 つリストする必要があります。

これは私が試したものですが、辞書を渡すことができません:

    Public Sub BuildOrderOptions(nameorder As ComboBox, Options As Dictionary(Of String, [Enum]))

    nameorder.Items.Clear()

    For Each item In Options
        nameorder.Items.Add(item)
    Next
    nameorder.DisplayMember = "Key"
    nameorder.ValueMember = "Value"
End Sub

Property NameOrderOptions As New Dictionary(Of String, PersonList.orderOption) From {{"First Name", PersonList.orderOption.FirstName},
                                                                                   {"Last Name", PersonList.orderOption.LastName},
                                                                                   {"Room Number", PersonList.orderOption.RoomNumber}}

Property DateOrderOptions As New Dictionary(Of String, OrderDate) From {{"Newest First", OrderDate.NewestFirst}, {"Oldest First", OrderDate.OldestFirst}}

Type と [enum].getnames などでいくつかのバリエーションを試しましたが、異なる辞書タイプをまったく渡すことができません - 今までにビジネス全体を複雑にしすぎたと思いますが、エレガントなソリューションが欠けていると感じています. すぐに、文字列マッチングのみに戻すか、ボックス タイプごとに機能を持たせるだけにします - 邪悪な重複ですが、先に進むことができます。

これを行うためのより良い方法があると考えるのは正しいですか?オプション用にある種のグローバルリソースを定義しない限り、おそらく-しかしグローバルは悪いですよね?

編集: Steven のおかげで修正されました。誰かがそれを便利だと思うか、もっと良いと思う場合は、誰でも批評してより良くすることができます。ここに、すべてのフォームがオプションを生成するために使用できるモジュールコードがあります。

Public Sub BuildOrderOptions(nameorder As ComboBox, Options As IDictionary)
    nameorder.Items.Clear()
    For Each item In Options
        nameorder.Items.Add(item)
    Next
    nameorder.DisplayMember = "Key"
    nameorder.ValueMember = "Value"
End Sub

Property NameOrderOptions As New Dictionary(Of String, orderOption) From {{"First Name", orderOption.FirstName},
                                                                                   {"Last Name", orderOption.LastName},
                                                                                   {"Room Number", orderOption.RoomNumber}}

Property DateOrderOptions As New Dictionary(Of String, OrderDate) From {{"Newest First", OrderDate.NewestFirst}, {"Oldest First", OrderDate.OldestFirst}}

Property personStatusOptions As New Dictionary(Of String, personStatus) From {{"Active", personStatus.Active},
                                                                                  {"InActive", personStatus.InActive},
                                                                                  {"All", personStatus.All}}

Public Sub BuildComboBoxes(ListBoxes As Dictionary(Of ComboBox, IDictionary))
    For Each pair In ListBoxes
        BuildOrderOptions(pair.Key, pair.Value)
    Next
End Sub

Public Enum OrderDate
    OldestFirst
    NewestFirst
End Enum

Public Enum personStatus
    Active
    InActive
    All
End Enum

Public Enum orderOption
    None
    FirstName
    LastName
    RoomNumber
End Enum

そして、これを使用して 1 つのフォームを取得する方法は次のとおりです。はい、パラメーターの束または複数の関数呼び出しを使用することもできました。渡すパラメーターを 1 つ与える単一のオブジェクトを使用するのが好きです。

   BuildComboBoxes( New Dictionary ( Of ComboBox , IDictionary ) From {{NameOrder, NameOrderOptions},
                                                                   {DateOrder, DateOrderOptions},
                                                                   {personStatus, PersonStatusOptions}})
4

1 に答える 1

2

IDictionary特定の種類の辞書ではなく、任意のオブジェクトを受け入れるようにメソッドを変更するだけです。

Public Sub BuildOrderOptions(nameorder As ComboBox, Options As IDictionary)

などのジェネリックを使用している場合Dictionary(Of TKey, TValue)、ジェネリック型は実際には型ではありません。これは、任意の数の特定の型のテンプレートのように考えることができます。したがって、異なる型パラメーターを使用してジェネリック型を使用するたびに、それらは完全に異なり、互換性のない型になります。例えば:

' This works fine because both d1 and d2 are exactly the same type
Dim d1 As New Dictionary(Of String, String)()
Dim d2 As Dictionary(Of String, String) = d1

' This will not compile because d1 and d2 are completely different types
Dim d1 As New Dictionary(Of String, Integer)()
Dim d2 As Dictionary(Of String, Boolean) = d1

お気づきのように、基本クラスをジェネリック型パラメーターとして使用しようとしても、2 つは互換性がありません。したがって、Streamは の基本クラスですがMemoryStream、これを行うことはできません。

' This will not compile because d1 and d2 are completely different types
Dim d1 As New Dictionary(Of String, MemoryStream)()
Dim d2 As Dictionary(Of String, Stream) = d1
于 2012-12-31T12:34:58.097 に答える