【问题标题】:DataBinding a Combobox to custom object fails to show data将 Combobox 绑定到自定义对象的数据无法显示数据
【发布时间】:2013-06-04 00:54:55
【问题描述】:

我在将对象数据绑定到 VB.NET (VS2008/.NET 3.5) 中的组合框时遇到问题。请看一下我的代码的简化版本:

Friend Class clDocument
    Private _items as New List(Of clDocumentItems)

    <System.ComponentModel.DisplayName("Items")> _
    <System.ComponentModel.Bindable(True)> _
    Public Property Items() As List(Of clDocumentItems)
        Get
            Return _items
        End Get
        Set(ByVal value As List(Of clDocumentItems))
            _items = value
            RaiseEvent ItemsChanged(Me, New EventArgs)
        End Set
    End Property

    Public Event ItemsChanged As EventHandler
End Class
Friend Class clDocumentItems
    Private _uid as String = ""
    Private _docnumber as String = ""

    <System.ComponentModel.DisplayName("UID")> _
    <System.ComponentModel.Bindable(True)> _
    Public Property UID() As String
        Get
            Return _uid
        End Get
        Set(ByVal value As String)
            _uid = value
            RaiseEvent UIDChanged(Me, New EventArgs)
        End Set
    End Property
    <System.ComponentModel.DisplayName("Document")> _
    <System.ComponentModel.Bindable(True)> _
    Public Property DocNumber() As String
        Get
            Return _docnumber
        End Get
        Set(ByVal value As String)
            _docnumber = value
            RaiseEvent DocNumberChanged(Me, New EventArgs)
        End Set
    End Property

    Public Event UIDChanged As EventHandler
    Public Event DocNumberChanged As EventHandler
End Class

在其他地方,我们得到了这个代码:

Private Sub cmd_go_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd_go.Click
        'Try to load the object with data, this works well
        Dim _document as New clDocument
        _document.Load(somevalue)

        cmb_docs.DataSource = Nothing
        cmb_docs.Items.Clear()
        If _document.UID = "" Then Exit Sub 'Object wasn't loaded so get out

        'Create the binding.     
        cmb_docs.ValueMember = "UID"
        cmb_docs.DisplayMember = "DocNumber"
        cmb_docs.DataSource = _document.Items
End Sub

现在,问题是 ComboBox 填充了与 _document.Items 中的对象一样多的项目,但它不传递真实数据 - 组合框填充了“Namespace.clDocumentItems”字符串。请注意,当绑定到常规类属性(字符串、整数等)时,类似的代码也能完美运行。

现在,我可以通过使用调试器的反射来猜测这是因为 Datsource 正在接收对象列表而不是字段,但是我不知道如何避免这种情况而不必创建另一个数组或列表只是这些值并将其传递给 Datasource 属性...

我探索了该网站以寻找类似的东西,唯一接近的是 this question,它在 3 年前没有得到答复,所以我希望今天有更好的运气;)

感谢您的宝贵时间!

编辑:下面我根据 cmets 中的要求将用于数据绑定的代码添加到 DataGridView。

    Private WithEvents _bs as New BindingSource

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        DataGridView1.AutoGenerateColumns = False
        Dim column As DataGridViewColumn = New DataGridViewTextBoxColumn()
        column.DataPropertyName = "Document"
        column.Name = "colDoc"
        DataGridView1.Columns.Add(column)

        _bs.DataSource = _document.Items 
        Me.DataGridView1.DataSource = _bs
    End Sub

【问题讨论】:

    标签: vb.net visual-studio data-binding binding


    【解决方案1】:

    您的代码实际上没有任何问题,正如您在上面编写的那样(我将它复制到一个新的 WinForms 应用程序中,提供了一些默认值,并且它工作正常)。

    您的实施可能无法正常工作有两个可能的原因:

    1. 如果 DisplayMember 中有错字。

    2. 如果 DisplayMember 属性的访问级别阻止 组合框无法访问它。

    如果无法找到或访问该属性,.Net 将退回到使用对象的 ToString 方法的默认实现。因此,一种快速而肮脏的解决方法是覆盖 clDocument 的 ToString 方法并返回 DocNumber。这应该可以解决显示问题,但不能解决问题的根本原因,这需要更多研究。

    【讨论】:

    • 好吧,事实证明您的第 2 点是正确的。我也怀疑这些课程是“朋友”而不是公开的。事实证明: - 使用该代码我可以绑定到“直接”实例,完全没有问题,即使定义了 Friend。 - 但如果对象是嵌套的,则所述嵌套对象必须是 Public,即使父对象是 Friend。否则它不会绑定到属性。有趣的是,使用那些嵌套的 Friend 类并没有在使用 BindingSource 的 DataGrid 控件上造成任何问题... >.> 再次感谢!
    • @KalaNag 你是如何使用 BindingSource 绑定它的?可以举个例子吗?
    【解决方案2】:

    好的,问题是组合框有问题。从表单中删除控件并再次添加它可以解决问题。我接受这个答案,因为它包含有用的信息。

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多