Vb.net 将组合框数据绑定到自定义对象时无法显示数据

Vb.net 将组合框数据绑定到自定义对象时无法显示数据,vb.net,visual-studio,data-binding,binding,Vb.net,Visual Studio,Data Binding,Binding,我在VB.NET(VS2008/.NET 3.5)中将对象数据绑定到组合框时遇到问题。请查看我的代码的简化版本: Friend Class clDocument Private _items as New List(Of clDocumentItems) <System.ComponentModel.DisplayName("Items")> _ <System.ComponentModel.Bindable(True)> _ Publi

我在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
现在,问题是组合框中填充的项目与_document.items中的对象数量相同,但它不传递真实数据-组合框中填充了“Namespace.clDocumentItems”字符串。请注意,当绑定到常规类属性(字符串、整数等)时,类似的代码可以完美地工作

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

我在网站上搜索了一些类似的东西,唯一接近的是3年前没有得到回复,所以我希望今天运气更好;)

谢谢你的时间

编辑:下面我将用于数据绑定的代码添加到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

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

有两个可能的原因导致您的实现无法工作:

  • 如果DisplayMember中有输入错误

  • 如果DisplayMember属性的访问级别阻止 combobox无法访问它


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

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

    有两个可能的原因导致您的实现无法工作:

  • 如果DisplayMember中有输入错误

  • 如果DisplayMember属性的访问级别阻止 combobox无法访问它


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

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


    谢谢

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


    谢谢

    事实证明你的观点2是正确的。我也怀疑这些课程是“朋友”而不是公众。事实证明:-使用该代码,我可以绑定到“直接”实例,一点问题都没有,即使定义为Friend但如果对象是嵌套的,则所述嵌套对象必须是公共的,即使父对象是朋友。否则它将不会绑定到属性。有趣的是,在使用BindingSource的DataGrid控件上使用这些嵌套的Friend类并没有引起任何问题…>。>再次感谢@KalaNag您是如何使用BindingSource绑定它的?你能给我举个例子吗?事实证明你的观点2是正确的。我也怀疑这些课程是“朋友”而不是公众。事实证明:-使用该代码,我可以绑定到“直接”实例,一点问题都没有,即使定义为Friend但如果对象是嵌套的,则所述嵌套对象必须是公共的,即使父对象是朋友。否则它将不会绑定到属性。有趣的是,在使用BindingSource的DataGrid控件上使用这些嵌套的Friend类并没有引起任何问题…>。>再次感谢@KalaNag您是如何使用BindingSource绑定它的?你能给我举个例子吗?
        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