【问题标题】:How to databind to a dropdown list of user defined types?如何将数据绑定到用户定义类型的下拉列表?
【发布时间】:2009-09-05 14:40:44
【问题描述】:

我有一个包含星期几的下拉列表 - 星期一到星期日。它填充了用户定义的两个值类型,将一周中的数字日期映射到它的名称。

Public Structure WeekDays
   Public ID As Integer
   Public Text As String
   Public Overrides Function ToString() As String
       Return Me.Text
   End Function
End Structure

我要绑定的对象有一个整数属性DayOfWeek,我想将下拉列表中选中项的ID值绑定到对象的DayOfWeek属性。例如。用户选择星期四,将 ID 4 传递给对象。

在代码中,我可以检索 SelectedItem 的 UDT,但无法确定要绑定到组合框上的哪个属性。

  1. 如果我将 UDT 直接添加到下拉列表的 Items 集合中,则 SelectedValue 为 Nothing。
  2. 如果我将 UDT 添加到 List(Of UDT) 集合并将其设置为下拉列表的数据源,同时 ValueMember 设置为 ID,DisplayMember 设置为 Text,则 SelectedValue 返回整个 UDT,而不是 ID ValueMember 属性。

数据绑定似乎对纯文本框非常有效,但在处理更复杂的控件时似乎变得更加棘手。

更新:我正在寻找的是 Binding 语句。例如。也没有……

oB = New Binding("SelectedItem", Payroll, "DayOfWeek")
oB = New Binding("SelectedItem.ID", Payroll, "DayOfWeek")

... 有效。第一个被忽略(可能是因为 SelectedItem 属性为 Nothing),第二个失败并出现“无法绑定...”错误。

【问题讨论】:

    标签: .net winforms data-binding business-objects


    【解决方案1】:

    创建属性,

    Public Structure WeekDays
        Private _ID As Integer
        Private _Text As String
        Public Sub New(ByVal ID As Integer, ByVal Text As String)
            Me._ID = ID
            Me._Text = Text
        End Sub
        Public Overrides Function ToString() As String
            Return Me._Text
        End Function
    
        Public Property ID() As Integer
            Get
                Return _ID
            End Get
            Set(ByVal value As Integer)
                _ID = value
            End Set
        End Property
        Public Property Text() As String
            Get
                Return _Text
            End Get
            Set(ByVal value As String)
                _Text = value
            End Set
        End Property
    End Structure
    
    
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim items As New List(Of WeekDays)
    
            items.Add(New WeekDays(1, "A"))
            items.Add(New WeekDays(2, "B"))
    
            Dim lb As New ListBox
            lb.DataSource = items
            lb.ValueMember = "ID"
            lb.DisplayMember = "Text"
            AddHandler lb.SelectedIndexChanged, AddressOf Item_Sel
    
            Me.Controls.Add(lb)
    
            TextBox1.DataBindings.Add(New Binding("Text", items, "Text"))
    
            Dim cb As New ComboBox
            cb.DataSource = items
            cb.DisplayMember = "Text"
            cb.ValueMember = "ID"
            cb.DataBindings.Add("SelectedValue", items, "ID")
            cb.Location = New Point(100, 100)
            Me.Controls.Add(cb)
            TextBox1.DataBindings.Add(New Binding("Text", items, "ID"))           
        End Sub
    
        Public Sub Item_Sel(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim obj As Object = CType(sender, ListBox).SelectedValue
            MsgBox(obj)
        End Sub
    End Class
    

    【讨论】:

    • 嗯。我看不出为什么属性会与公共字段有任何不同,但我还是尝试了这个。在它不起作用之后,我尝试从 UDT 更改为 Class,但这也不起作用。我认为您的示例有效,因为您绑定到 Text 属性(它恰好存在于组合和 UDT 中)。我需要能够绑定到 ID 值,但是 DataBindings.Add 操作在 COMBO 上找不到 ID 属性并导致错误。
    • 不,它与 ComboBox 属性无关。您可以将 ValueMember 和 DisplayMember 设置为数据项的任何公共属性
    【解决方案2】:

    好的,所以我找到了可能的解决方案。

    我创建了自己的 ComboBox 控件,它继承了标准 WinForms.ComboBox 并添加了一个名为 SelectedID 的额外 Integer 属性。

    Public Structure NumericUDT
       Public ID As Integer
       Public Text As String
    
       Public Sub New(ByVal iID As Integer, ByVal sText As String)
           Me.ID = iID
           Me.Text = sText
       End Sub
       Public Overrides Function ToString() As String
           Return Me.Text
       End Function
    End Structure
    
    Public Property SelectedID() As Integer
        Get
            Dim uItem As NumericUDT
            Dim iID As Integer
    
            If (MyBase.SelectedItem Is Nothing) Then
                iID = 0
            Else
                uItem = DirectCast(MyBase.SelectedItem, NumericUDT)
                iID = uItem.ID
            End If
    
            Return iID
    
        End Get
        Set(ByVal value As Integer)
    
            Dim uItem As NumericUDT
            Dim uFound As NumericUDT = Nothing
    
            For Each uItem In MyBase.Items
                If uItem.ID = value Then
                    uFound = uItem
                    Exit For
                End If
            Next
    
            MyBase.SelectedItem = uFound
    
        End Set
    End Property
    

    这允许我绑定到 SelectedID 属性...

       oB = New Binding("SelectedID", Payroll, "PayDay")
    

    ...似乎工作正常。

    【讨论】:

    • 我会等几天看看是否有更好的解决方案,否则我会接受这个答案。
    猜你喜欢
    • 2011-12-14
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多