我只是在这里抛砖引玉,这其中好多结果都是参照其他技术人员的一些例子和介绍,不过我始终没有找到全面的介绍(就是事无具细的)不过这样也好,所以只能自己摸索,这其中我也有好多不解之处.
我就按我如何来解决这些问题来写写.
我的自定义对象集合是是继承于CollectionBase的.因为CollectionBase已经实现了ILIST接口,也就是说可能直接绑定到了DataGrid控件.但是在默认情况自定义类的公共属性都会绑定到datagrid.这显然是不符合要求的.
按我们实际使用情况如下:
1.可以指定要绑定的属性.
2.可以控制绑定属性的列位置.
这时通过查msdn发现了接口ItypedList好像可以实现这些要求.通过google也找到一个关于绑定的例子.如何实现itypedlist接口.最重要的接口方法是GetItemProperties,他就能控制你自定义的那些属性可以进行绑定.返回的值是PropertyDescriptorCollection集合,所以我们需要实现一个自定义属性描述的类CustomPropertyDescriptor它的基类是System.ComponentModel.PropertyDescriptor.重写其抽象方法.其中要注意的是IsReadOnly属性,这个属性就可以控制在datagrid控件中是否允许编辑此属性.
CustomPropertyDescriptor的实现

Public Class CustomPropertyDescriptorClass CustomPropertyDescriptor
Inherits System.ComponentModel.PropertyDescriptor


Private md_name As String = String.Empty
Private md_pi As System.Reflection.PropertyInfo
Private md_attribute As FieldAttribute


Public Sub New()Sub New(ByVal name As String, ByVal pi As System.Reflection.PropertyInfo)
MyBase.New(name, pi.GetCustomAttributes(GetType(Attribute), True))
Me.md_name = name
Me.md_pi = pi

End Sub


Public Overrides Function GetValue()Function GetValue(ByVal component As Object) As Object
'Debug.WriteLine("GetValue")
Return CType(component, EntityBase).GetValue(Me.md_pi.Name)
End Function


Public Overrides ReadOnly Property ComponentType()Property ComponentType() As System.Type
Get
Return Me.md_pi.DeclaringType
End Get
End Property


Public Overrides ReadOnly Property PropertyType()Property PropertyType() As System.Type
Get
Return Me.md_pi.PropertyType
End Get
End Property


Public Overrides Sub ResetValue()Sub ResetValue(ByVal component As Object)

End Sub


Public Overrides Sub SetValue()Sub SetValue(ByVal component As Object, ByVal value As Object)
'Debug.WriteLine("SetValue")
CType(component, EntityBase).SetValue(Me.md_pi.Name, value)
End Sub


Public Overrides Function CanResetValue()Function CanResetValue(ByVal component As Object) As Boolean
Return False
End Function


Public Overrides Function ShouldSerializeValue()Function ShouldSerializeValue(ByVal component As Object) As Boolean
Return False
End Function


Public Overrides ReadOnly Property IsReadOnly()Property IsReadOnly() As Boolean
Get
Return Not Me.md_pi.CanWrite
End Get
End Property

End Class
以下强类型集合的实现
Public Class EntityContainer
Inherits CollectionBase
Implements ITypedList, IBindingList

ItypeList接口#Region "ItypeList接口"

Public Function GetItemProperties()Function GetItemProperties(ByVal listAccessors() As System.ComponentModel.PropertyDescriptor) As System.ComponentModel.PropertyDescriptorCollection Implements System.ComponentModel.ITypedList.GetItemProperties

If Me.ItemType Is Nothing Then
Throw New PersistenceLayerException("执行绑定失败,没有指定容器的属性ItemType.")
Else
Dim en As EntityBase = Activator.CreateInstance(Me.ItemType)
Return New System.ComponentModel.PropertyDescriptorCollection(en.GetCustomProperties)
End If
End Function


Public Function GetListName()Function GetListName(ByVal listAccessors() As System.ComponentModel.PropertyDescriptor) As String Implements System.ComponentModel.ITypedList.GetListName
If Me.ItemType Is Nothing Then
Throw New PersistenceLayerException("执行绑定失败,没有指定容器的属性ItemType.")
Else
Return Me.ItemType.Name
End If
End Function
#End Region
以前就是我的ItypedList接口的实现其中属性ItemType是指定我当前集合中存放的实体类型.我已定义的实体具有方法GetCustomProperties就是用于返回我当前实体那些属性是允许进行绑定的.

IBindingList接口实现#Region "IBindingList接口实现"


公共#Region "公共"
''' -----------------------------------------------------------------------------
''' <summary>
''' 将新项添加到列表。
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Public Function AddNew()Function AddNew() As Object Implements System.ComponentModel.IBindingList.AddNew
If Not AllowNew Then Throw New InvalidOperationException("AddNew is not allowed.")
Dim en As EntityBase = Activator.CreateInstance(Me.ItemType)
List.Add(en)

'集合发生改变
OnListChanged(New ListChangedEventArgs(ListChangedType.ItemAdded, List.Count - 1))

'注册事件
AddHandler en.RemoveMe, AddressOf Me.RemoveMe

Return en
End Function

Public Event ListChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs) Implements System.ComponentModel.IBindingList.ListChanged

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取当列表更改或列表中的项更改时是否引发 ListChanged 事件.默认是True
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Public ReadOnly Property SupportsChangeNotification()Property SupportsChangeNotification() As Boolean Implements System.ComponentModel.IBindingList.SupportsChangeNotification
Get
Return True
End Get
End Property

#End Region


私有#Region "私有"

''' -----------------------------------------------------------------------------
''' <summary>
''' 将 PropertyDescriptor 添加到用于搜索的索引。
''' </summary>
''' <param name="property"></param>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private Sub AddIndex()Sub AddIndex(ByVal [Property ]()property] As System.ComponentModel.PropertyDescriptor) Implements System.ComponentModel.IBindingList.AddIndex

End Sub


Private ReadOnly Property AllowEdit1()Property AllowEdit1() As Boolean Implements System.ComponentModel.IBindingList.AllowEdit
Get
Return Me.AllowEdit
End Get
End Property


Private ReadOnly Property AllowNew1()Property AllowNew1() As Boolean Implements System.ComponentModel.IBindingList.AllowNew
Get
Return Me.AllowNew
End Get
End Property


Private ReadOnly Property AllowRemove()Property AllowRemove() As Boolean Implements System.ComponentModel.IBindingList.AllowRemove
Get
Return Me.AllowDelete
End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' 根据 PropertyDescriptor 和 ListSortDirection 对列表进行排序。
''' </summary>
''' <param name="property"></param>
''' <param name="direction"></param>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private Sub ApplySort()Sub ApplySort(ByVal [Property ]()property] As System.ComponentModel.PropertyDescriptor, ByVal direction As System.ComponentModel.ListSortDirection) Implements System.ComponentModel.IBindingList.ApplySort

End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' 返回具有给定 PropertyDescriptor 的行的索引。
''' </summary>
''' <param name="property"></param>
''' <param name="key"></param>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private Function Find()Function Find(ByVal [Property ]()property] As System.ComponentModel.PropertyDescriptor, ByVal key As Object) As Integer Implements System.ComponentModel.IBindingList.Find

End Function

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取是否对列表中的项进行排序。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private ReadOnly Property IsSorted()Property IsSorted() As Boolean Implements System.ComponentModel.IBindingList.IsSorted
Get

End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' 从用于搜索的索引中移除 PropertyDescriptor。
''' </summary>
''' <param name="property"></param>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private Sub RemoveIndex()Sub RemoveIndex(ByVal [Property ]()property] As System.ComponentModel.PropertyDescriptor) Implements System.ComponentModel.IBindingList.RemoveIndex

End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取排序的方向。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private ReadOnly Property SortDirection()Property SortDirection() As System.ComponentModel.ListSortDirection Implements System.ComponentModel.IBindingList.SortDirection
Get

End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取列表是否支持排序。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private ReadOnly Property SupportsSorting()Property SupportsSorting() As Boolean Implements System.ComponentModel.IBindingList.SupportsSorting
Get
Return False
End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取列表是否支持使用 Find 方法进行搜索。默认是False
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private ReadOnly Property SupportsSearching()Property SupportsSearching() As Boolean Implements System.ComponentModel.IBindingList.SupportsSearching
Get
Return False
End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' 使用 ApplySort 移除任何已应用的排序。
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private Sub RemoveSort()Sub RemoveSort() Implements System.ComponentModel.IBindingList.RemoveSort

End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' 获取正在用于排序的 PropertyDescriptor。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------

Private ReadOnly Property SortProperty()Property SortProperty() As System.ComponentModel.PropertyDescriptor Implements System.ComponentModel.IBindingList.SortProperty
Get

End Get
End Property
#End Region

#End Region
实现了ItypedList接口,虽然我们绑定到datagrid已实现了我们的要求,但是这时,不能编辑,不能添加,不能删除,如果要实现这些功能,我们就需要实现IBindingList接口.这个接口主要是用于是否允许编辑,是否允许移除,排序,查找等,排序和查找我没有实现.
这时我以为现在可以正常的完成了绑定,不过事情还没有完,我在进行编辑的时候,有时会有异常产生,在通过google查询绑定方面的资料时,对集合的项目进行改变时要引ListChanged事件.
所以需要重写CollectionBase的一些方法