初期.
定义了一个实体的强类型集合.
继承于CollectionBase
由于CollectionBase已经实现了IList接口,我的实体也可以绑定到了datagrid.
默认只要是类的公共属性都会出现在datagrid中.这不是我想要的.翻了一下msdn和在网上查了一下资料,需要使用接口ItypeList才能实现我的要求.
ITypedList接口介绍
提供发现可绑定列表架构的功能,其中可用于绑定的属性不同于要绑定到的对象的公共属性。例如,当使用表示客户表的 DataView 时,您要绑定到 DataView 表示的客户对象上的属性,而不是 DataView 的属性。
接口方法:
GetItemProperties
GetListName
其中最重要的是GetItemProperties 方法,实现它就能自由灵活的控制,要绑定的属性列表.
![](/Images/OutliningIndicators/ContractedBlock.gif)
ItypeList接口#Region "ItypeList接口"
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Function GetItemProperties()Function GetItemProperties(ByVal listAccessors() As System.ComponentModel.PropertyDescriptor) As System.ComponentModel.PropertyDescriptorCollection Implements System.ComponentModel.ITypedList.GetItemProperties
![](/Images/OutliningIndicators/InBlock.gif)
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
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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
其中方法:GetCustomProperties是用于实体类的那些属性是允许绑定的一个数组.
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
''' -----------------------------------------------------------------------------
''' <summary>
''' 返回进行绑定的属性列表.
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-09-02 Created
''' </history>
''' -----------------------------------------------------------------------------
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Overridable Function GetCustomProperties()Function GetCustomProperties() As CustomPropertyDescriptor()
Dim cp(Me.BindAttributeList.Count - 1) As CustomPropertyDescriptor
Dim i As Integer
For Each str As String In Me.BindAttributeList
cp(i) = (New CustomPropertyDescriptor(str, Me.GetType.GetProperty(str)))
i += 1
Next
![](/Images/OutliningIndicators/InBlock.gif)
Return cp
End Function
同时我们还需要实现描述属性的类CustomPropertyDescriptor继承于System.ComponentModel.PropertyDescriptor
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class CustomPropertyDescriptorClass CustomPropertyDescriptor
Inherits System.ComponentModel.PropertyDescriptor
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
Private md_name As String = String.Empty
Private md_pi As System.Reflection.PropertyInfo
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub New()Sub New(ByVal name As String, ByVal pi As System.Reflection.PropertyInfo)
MyBase.New(name, pi.GetCustomAttributes(GetType(FieldAttribute), True))
Me.md_name = name
Me.md_pi = pi
![](/Images/OutliningIndicators/InBlock.gif)
End Sub
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides Function GetValue()Function GetValue(ByVal component As Object) As Object
![](/Images/OutliningIndicators/InBlock.gif)
Return CType(component, EntityBase).GetValue(Me.md_pi.Name)
End Function
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides ReadOnly Property ComponentType()Property ComponentType() As System.Type
Get
Return Me.md_pi.DeclaringType
End Get
End Property
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides ReadOnly Property PropertyType()Property PropertyType() As System.Type
Get
Return Me.md_pi.PropertyType
End Get
End Property
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides Sub ResetValue()Sub ResetValue(ByVal component As Object)
End Sub
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides Sub SetValue()Sub SetValue(ByVal component As Object, ByVal value As Object)
CType(component, EntityBase).SetValue(Me.md_pi.Name, value)
End Sub
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides Function CanResetValue()Function CanResetValue(ByVal component As Object) As Boolean
Return False
End Function
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides Function ShouldSerializeValue()Function ShouldSerializeValue(ByVal component As Object) As Boolean
Return False
End Function
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Overrides ReadOnly Property IsReadOnly()Property IsReadOnly() As Boolean
Get
Return Not Me.md_pi.CanWrite
End Get
End Property
![](/Images/OutliningIndicators/InBlock.gif)
End Class
这样就算定义完成了,可能实现在实体的绑定.
如果还需要在datagrid中进行编辑,添加,移除,排序等操作.还要在实体集合上实现IBindingList接口.
下面是我的持久层实现在对实体集合进行编辑的代码:
获取实体集合
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
'实例化实体
Dim t As New t
![](/Images/OutliningIndicators/None.gif)
'实体操作类
Dim ea As New Lily.PersistenceLayer.PersistenceLayerAdapter
'实体查询对象
Dim sc As New Lily.PersistenceLayer.SelectCommand
'只取前面50条
sc.Top = 500
'添加要查询数据的表
sc.FromSoure.AddFrom(t)
'查询对象添加到操作适配器中
ea.AddEntityCommand(sc)
'获取结果
Dim ec As Lily.PersistenceLayer.EntityContainer = ea.GetEntityContainer(GetType(t))
ec.ItemType = GetType(t)
'把实体集合绑定到datagrid
Me.DataGrid1.DataSource = ec
在datagrid中编辑之后,保存实体
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
'持久层操作对象
Dim da As New Lily.PersistenceLayer.PersistenceLayerAdapter
Try
da.DataHelper.BeginTransaction() '开始事务
'先删除,如果没有指定条件对象,则把实体对应所有的数据都删除
da.AddEntityCommand(New Lily.PersistenceLayer.DeleteCommand(New t, Nothing))
![](/Images/OutliningIndicators/None.gif)
'获取对象集合
Dim ec As Lily.PersistenceLayer.EntityContainer = Me.DataGrid1.DataSource
'编历把插入命令对象加入到操作对象中
For Each en As t In ec
da.AddEntityCommand(New Lily.PersistenceLayer.InsertCommand(en))
Next
![](/Images/OutliningIndicators/None.gif)
'执行操作
'这里才开始把之前进行更新
da.Update()
![](/Images/OutliningIndicators/None.gif)
da.DataHelper.Commit() '提交事务
Catch ex As Exception
da.DataHelper.Rollback()
MsgBox(ex.ToString)
End Try
还没有处理的问题
1.在进行实体的插入后,把自动增长字段的值更新到实体
2.实体的属性发生改变后,绑定的控件也能实时发应,.net2.0到有一个接口INotifyPropertyChanged可以实现,不知道.net1.1有没有这样的接口,知道的朋友请踢教.