0

这可能是不可能的或有点错误,但是在 WinForms 中,我有需要填充特定选项的组合框。该项目使用了大约 10 种不同的表单,所有表单都具有相似但略有不同的功能:因此我不只使用一种表单并根据需要隐藏/显示控件。

现在,我制作了一个简单的选项字典,并使用 Enum 输入值。现在我意识到我有重复的代码并想合并它。选项集是日期顺序和名称顺序,但我还有一两个要列出。

这是我尝试过但无法将字典传递到:

    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 等的一些变体,但我根本无法传递不同的字典类型 - 我认为我现在已经使整个业务过于复杂,但我觉得我错过了一个优雅的解决方案. 很快,我要么单独转换回字符串匹配,要么只为每个盒子类型提供函数——邪恶的重复,但我可以继续。

我是否认为有更好的方法可以做到这一点?除非我只是为选项定义某种全局资源,否则全局资源很糟糕,对吧?

编辑:感谢史蒂文修复。如果有人发现它有用或更好,任何人都可以批评并做得更好,这是所有表单都可以用来生成选项的模块代码。

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

这就是我使用一个表单的方式——是的,我可以有一堆参数或多个函数调用:我只是喜欢有一个对象给我一个参数来传递。

   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

正如您所发现的,即使您尝试使用基类作为泛型类型参数,两者仍然不兼容。所以,即使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 回答