将Combobox DataBinding绑定到自定义对象无法显示数据

时间:2013-06-04 00:54:55

标签: 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)> _
    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”字符串。请注意,类似的代码在绑定到常规类属性(String,integer等)时可以正常工作。

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

我在网站上搜索了类似的东西,唯一接近的是this question 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

2 个答案:

答案 0 :(得分:1)

你的代码实际上没有任何错误,因为你已经在上面写了它(我将它复制到一个新的WinForms应用程序,提供了一些默认值,并且它正常工作)。

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

  1. 如果DisplayMember中有拼写错误。

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

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

答案 1 :(得分:0)

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

由于