且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将一组对象绑定到DataGridView中的ComboboxColumn

更新时间:2022-10-21 08:48:22

我发现很多错误来自我对各种文章的误解已经阅读了,以及乱码。



我忽略了在一些属性上指定返回类型,选项显式/选项严格都关闭,并且有在我的设计师中有一些腐败,一些列被重复。



我最喜欢的一个解决方案是: http://code.google.com/p/systembusinessobjects/source/ browse / trunk / System.BusinessObjects.Framework / Data / SafeBindingLists.cs 。不幸的是,这需要Castle代理和旧版NHibernate。



这是我找到的简单解决方案:



问题是您无法将列表与多种类型的对象绑定。目标是使ComboBox能够直接将属性的值设置为与另一个对象绑定的对象。



我选择使用View对象,并绑定到该列表。



查看对象:

 公共类OwnerView 
私有_所有者作为所有者

公共ReadOnly属性OwnerId As Integer
获取
返回_owner.OwnerId
结束获取
结束属性

公开ReadOnly属性OwnerName As String
获取
返回_owner.OwnerName
结束获取
结束属性

公共ReadOnly属性所有者缩写As String
获取
返回_owner.OwnerAbbreviation
结束获取
结束属性

公共可覆盖ReadOnly属性自己作为所有者
获取
返回_owner
结束获取
结束属性

公共子N ew(ByVal owner As Owner)
_owner = owner
End Sub

结束类

绑定:

  With OwnerColumn 
.SortMode = DataGridViewColumnSortMode.Automatic
.ReadOnly = False
.Name =OwnerColumn
.HeaderText =Owner

Dim bs As New BindingSource()

对于每个co作为所有者的所有者
bs.Add(新OwnerView(co))
下一个

.DataPropertyName =所有者
.DataSource = bs
.ValueMember =Self
.DisplayMember =OwnerName

ItemDataGridView.Columns.Add(OwnerColumn)
结束
/ pre>

I have a GUI which allows the user to select a report to view/edit. When the user selects a report, it shows the Items in the report. The Item has many properties - most of which are binding properly. One of the properties is Owner, and this is bound to a ComboBoxColumn.

  • Report
    • Items
      • Owner

I have done something very similar to this a few times and had no problems when I set the DataPropertyName, DataSource, ValueMember, and DisplayMember. The only difference is that this time instead of the Item type having an OwnderID it actually has an instance of the Owner object.

I saw a suggestion on another post to solve this issue by giving the items bound in the list a self-referencing property that allows them to return themselves for the purposes of setting the ValueMember

However, When I bind it this way:

OwnerColumn.DataPropertyName = "Owner"
OwnerColumn.DataSource = ownersBindingSource1
OwnerColumn.ValueMember = "Self"
OwnerColumn.DisplayMember = "OwnerName"

I get a lot of errors like:

Unable to cast object of type 'System.String' to type 'Owner'.

and:

The following exception occurred in the DataGridView:

System.ArgumentException: DataGridViewComboBoxCell value is not valid.

To replace this default dialog please handle the DataError event.

I was able to get around some of these errors by binding it like this:

OwnerColumn.DataPropertyName = "Owner"
OwnerColumn.DataSource = ownersBindingSource1

and also by making the ToString function on the Owner display the OwnerName property. This seems pretty hacky though - and I think I'm misunderstanding something fundamental as it still does not function properly. Any help would be much appreciated.

I found out that a lot of my errors were coming from my misunderstanding of various articles I had read, as well as sloppy code.

I neglected to specify the return type on a few of the properties, option explicit / option strict were both off, and there had been some corruption in my designer and a few of the columns were duplicated.

A solution to this that I liked the most was: http://code.google.com/p/systembusinessobjects/source/browse/trunk/System.BusinessObjects.Framework/Data/SafeBindingLists.cs . Unfortunately, this requires Castle proxy, and an older version of NHibernate.

Here is the simple solution that I found:

The issue is that you cannot bind a list with objects of multiple types. The goal is to be able to have the ComboBox directly set the value of a property on the object it is bound to with another object.

I chose to use a View object, and bind the list to that.

View Object:

Public Class OwnerView
    Private _owner As Owner

    Public ReadOnly Property OwnerId As Integer
        Get
            Return _owner.OwnerId
        End Get
    End Property

    Public ReadOnly Property OwnerName As String
        Get
            Return _owner.OwnerName
        End Get
    End Property

    Public ReadOnly Property OwnerAbbreviation As String
        Get
            Return _owner.OwnerAbbreviation
        End Get
    End Property

    Public Overridable ReadOnly Property Self As Owner
        Get
            Return _owner
        End Get
    End Property

    Public Sub New(ByVal owner As Owner)
        _owner = owner
    End Sub

End Class

Binding:

With OwnerColumn
    .SortMode = DataGridViewColumnSortMode.Automatic
    .ReadOnly = False
    .Name = "OwnerColumn"
    .HeaderText = "Owner"

    Dim bs As New BindingSource()

    For Each co As Owner In Owners
        bs.Add(New OwnerView(co))
    Next

    .DataPropertyName = "Owner"
    .DataSource = bs
    .ValueMember = "Self"
    .DisplayMember = "OwnerName"

    ItemDataGridView.Columns.Add(OwnerColumn)
End With