如何绑定ComboBox的选定成员?

时间:2015-12-09 16:39:52

标签: vb.net winforms binding combobox

我有一个ComboBox,其中填充了ProfileName

类型的对象
Private Class ProfileName
    Public Property Name As String
    Public Property File As String
    Public Property ProductVersion As String
End Class

在对一堆文件进行反序列化并从结果对象中复制一些值之后,会创建这些项目添加到组合框中:

    pcb.DisplayMember = "Name"
     For Each F As FileInfo In ProfileFiles
        Dim Reader As StreamReader = F.OpenText()
        Dim Serialize As Serializer = New Serializer()
        Dim SerializedData As String = Reader.ReadToEnd() 
        Dim P As Profile = Serialize.DesearializeObject(Of Profile)(SerializedData)

        If P.Type = Profile.ProfileType.Product Then
            Dim PN As ProfileName = New ProfileName()
            PN.File = F.Name
            PN.ProductVersion = P.ProductVersion
            PN.Name = P.ProductName & " - " & P.ProductVersion
            pcb.Items.Add(PN)
        End If
        Reader.Close()
    Next

然后,如果用户打开其中一个文件,该文件将再次反序列化,从而生成一个带有' ProductName'应该与ComboBox项目列表中已有项目之一匹配的属性,因此我希望ComboBox将其显示为所选项目。

即。 - 在表单加载时,ComboBox将填充所有可能的产品名称。 - 打开配置文件时,将在ComboBox中自动选择配置文件使用的产品。

我一直在玩

ProductComboBox.DataBindings.Add("SelectedValue", CurrentProfile, "ProductName")

及其排列,但似乎无法做到正确。

1 个答案:

答案 0 :(得分:1)

你无法混合和匹配 - 将对象放入items集合并使用数据绑定方法/元素。数据绑定基础:

Public Class Profile
    Public Property Name As String
    Public Property File As String
    Public Property ProductVersion As String

    Public Overrides Function ToString() As String
        Return String.Format("{0} ({1})", Name, ProductVersion)
    End Function
End Class

ToString()控制当您无法指定要显示的属性时将显示的内容。请注意,这些属性应该是属性,因为字段将被区别对待。

然后是他们的容器。这将是cbo的数据源。

Private Profiles As List(Of Profile)
...
' create instance of list and populate from where ever:
Profiles = New List(Of Profile)
Profiles.Add(New Profile With {.Name = "Default", .File = "foo",
            .ProductVersion = "1.0"})
Profiles.Add(New Profile With {.Name = "Ziggy", .File = "bat",
            .ProductVersion = "1.9.8"})
Profiles.Add(New Profile With {.Name = "Zoey", .File = "bar",
            .ProductVersion = "1.4.1"})

不是将Profile对象放入Items集合中,而是将控件绑定到List:

cboP.DataSource = Profiles
cboP.DisplayMember = "Name"

如果省略要显示的属性,则会显示ToString()(如果未覆盖,则为WindowsApp1.Profile)。注意:使用数据源时,您不再添加或删除控件的Items集合 - 它会对您大喊大叫。而是管理基础来源,在这种情况下为List(Of Profile)

要更改选择,例如更改为" Ziggy"

的选择
Dim n As Int32 = Profiles.FindIndex(Function(f) f.Name = "Ziggy")
If n > -1 Then
    cboP.SelectedIndex = n
End If

您也可以在找到SelectedItem之后设置Profile,但我倾向于使用索引。即使列表是一个新的演员,序列化整个事情也很容易:

' serializing the List acts on all the profiles in it
Dim json = JsonConvert.SerializeObject(Profiles)
File.WriteAllText("C:\Temp\Profiles.json", json)

回读:

json = File.ReadAllText("C:\Temp\Profiles.json")
Dim newPs = JsonConvert.DeserializeObject(Of List(Of Profile))(json)

它比通过一组文件循环更简单。 List(of T)有一整套方法和扩展来删除,排序,查找等,因此您应该获得项目集合或数组的功能。

或者,您可以为每个结构保留一个文件,但将反序列化的Profile对象添加到List(of Profile)而不是Items集合。