ADO.NET的数据绑定机制剖析及其应用
2007-12-28 09:46
357 查看
这是我写的书的一部分,全部原创,刚完成,欢迎提出意见。
bitfan
-------------------------------------------------------
7.5.2 在数据集中移动
当在程序中需要显示多条记录时,我们往往希望能给记录一个“记录号”以方便定位记录,比如:“到第一条”,“到最后一条”,“跳到第100条”……。 DataTable中的记录(即DataRow)本身并没有一个所谓的“记录号”,DataTable本身也没有提供这种功能。 提示:[/b] 在VB6中,记录集对象RecordSet提供MoveFirst,MoveLast等定位功能。这是由ADO实现的。在ADO.NET中,DataTable和DataRow都没有这些方法。 乍看起来,不能在数据集中移动,好象是ADO.NET设计的一个疏漏。事实上,ADO.NET把所有在数据集中定位的功能全部抽取出来,再加上其他一些功能,构建了ADO.NET的数据绑定机制,与原来ADO所提供的有限定位功能相比,ADO.NET更为强大而灵活。 请试着运行本书配套光盘中的示例MoveInDataTable,其运行界面如图 7 15:图 7 15 数据绑定示例 这个程序在运行时,既可以点击右下方的四个按钮,也可以直接点击上部的网格在数据集中移动,当前行的内容同步在下半部的两个文本框中显示。可以在文本框中直接修改数据,当移动到其它行时,网格中的记录同步刷新。 通过这个示例,我们来剖析ADO.NET中数据绑定机制的原理。
1 什么叫数据绑定?
所谓数据绑定,通俗地说,就是把数据源(如DataTable)中的数据取出来,显示在窗体的各种控件上,用户可以通过这些控件查看和修改数据,这些修改会自动地保存到数据源中,参见图 7 16。图 7 16 数据绑定原理 Windows 窗体可以利用两种类型的数据绑定:简单绑定和复杂绑定。这两种类型具有不同的优点。 l 简单绑定 简单数据绑定指将一个控件绑定到单个数据元素(如数据集表的列中的值)的能力。这是用于 TextBox 控件或 Label 控件等控件(即通常只显示单个值的控件)的典型绑定类型。 图 7 15中的两个文本框,分别绑定到了DataTable中的“AddressStr”和“ClientName”两个字段。l 复杂绑定 复杂数据绑定指将一个控件绑定到多个数据元素的能力,通常绑定到数据库中的多条记录。 图 7 15中的DataGrid就绑定到了一个DataTable,它可以一次显示多条记录和多个字段的值。
2 实现在数据集中移动
在数据集中移动是数据绑定机制中的一个子功能。 为了方便理解ADO.NET中复杂的数据绑定机制,我们先在MoveInDataTable示例中的一个简单的窗体内实现数据移动功能,参见图 7 17:图 7 17 手动实现在记录集中移动下面对代码进行分析(1)程序需要提取数据,Sub过程GetData实现这一功能: '定义相关变量 Private conn As OleDbConnection Private comm As OleDbCommand Private da As OleDbDataAdapter Private ds1 As New DataSet '获取数据 Private Sub GetData() '创建连接对象连接数据库 conn = New OleDbConnection conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/Clients.mdb;Persist Security Info=False" conn.Open() '创建命令对象用于向数据库发送SQL命令 comm = New OleDbCommand comm.CommandText = "select * from OrderClient" comm.CommandType = CommandType.Text comm.Connection = conn '创建DataAdapter用于填充DataSet da = New OleDbDataAdapter(comm) '填充数据 da.Fill(ds1) conn.Close() End Sub 注意,假设数据库Clients.MDB放在“D:/”下。这些代码我们已经很熟悉了。(2)设定数据绑定,Sub过程SetDataBing()实现这一功能: '数据绑定管理对象 Private cm As CurrencyManager '设置数据绑定 Private Sub SetDataBinding() '将DataGrid绑定到DataTable Me.DataGrid1.DataSource = ds1.Tables(0) '获取数据绑定管理对象 cm = Me.BindingContext(ds1.Tables(0)) End Sub 在示例程序的第二窗体(参见图 7 15)中,只不过是多了将文本框绑定到DataTable中的字段中的代码: Me.txtAddress.DataBindings.Add("Text", ds1.Tables(0), "AddressStr") Me.txtName.DataBindings.Add("Text", ds1.Tables(0), "ClientName") 可以看到,给DataGrid设置数据绑定非常简单,只需直接设定其DataSource属性就行了。 给文本框设置数据绑定,需要向其DataBindings集合增加一项,其格式为: "要绑定的属性名", 被绑定的DataTable对象, "DataTable中的字段名" 在上面的代码中,控件都是直接绑定到DataTable中的,事实上,也可直接绑定到DataSet,但这时需要对代码做一些改变: '将DataGrid绑定到DataTable Me.DataGrid1.DataSource = ds1 Me.DataGrid1.DataMember = ds1.Tables(0).TableName '绑定文本框 Me.txtAddress.DataBindings.Add("Text", ds1, ds1.Tables(0).TableName & ".AddressStr") Me.txtName.DataBindings.Add("Text", ds1, ds1.Tables(0).TableName & ".ClientName") 因为DataSet中可能会有多个DataTable,所以,必须给DataGrid的DataMember属性指明一个表名。在程序中动态指定某个DataTable表名,就可以动态地将DataGrid与此表名相对应的DataTable绑定。 文本框绑定的第三个参数被称为“绑定字串”,以英文句点隔开,其格式为: 表名.字段名 其特点是越左边的子字串其范围就越大。 技术内幕:[/b] 其实数据绑定不仅限于DataSet和DataTable,同样可以将文本框和DataGrid之类绑定到其它对象,如数组和ArrayList,这时,绑定字串就显得非常重要了,有兴趣的读者可以在MSDN中通过搜索“数据绑定”关键字了解如何绑定到非DataSet和DataTable数据。 (3)现在可以在记录集中移动了,这是通过给CurrencyManager的Position属性赋值实现的,下面列出了关键的代码: '移到第一条 cm.Position = 0 '移到前一条 If cm.Position > 0 Then cm.Position -= 1 End If '移到下一条 If cm.Position < cm.Count - 1 Then cm.Position += 1 End If '移到最后一条 cm.Position = cm.Count - 1 可以看到,在数据集中移动是通过CurrencyManager对象来实现的。 展示的代码虽然简单,但如果不理解这背后所隐藏的机制,还是无法充分地利用数据绑定机制的。
3 数据绑定原理
ADO.NET的数据绑定机制主要由以下类构成:图 7 18 数据绑定类 图 7 18以UML图符方式展示了ADO.NET中数据绑定的核心架构(注意,并没有完整地画出所有的类)。 提示: UML简称为Unified Modeling Language(统一建模语言),它使用图形的方式来表达面向对象的软件系统架构,目前已被软件业广泛接受,成为了国际标准。本书第四部分介绍面向对象编程中就大量地使用UML类图表达程序结构。本书附录中有一个UML基础教程,可供读者参考学习。 现在逐个介绍每个类。 从示例中我们已经知道,象文本框这样的控件都可以绑定到字段上,这一事实本身包含以下信息: 要绑定的自身属性(如Text属性) 提供数据来源的对象(如DataTable) 绑定导航字串 ………… 这些信息被封装起来,形成了Binding类。每个实现了数据绑定的控件都至少有一个Binding对象,表明它的绑定信息。 一个窗体上可能会有多个控件(比如多个文本框)绑定到一个数据源,这就意味着存在着多个Binding对象。因此需要有一个类来管理这些对象,这个类就是BindingManagerBase类,但这个类是个抽象类,不能直接创建对象,类CurrencyManager直接继承自BindingManagerBase类,实现了所有基类未实现的功能,可以直接被使用。在数据集中移动的功能就是由 CurrencyManager对象实现的。 现在知道了,要在数据集中移动,必须想法获取与此数据集对应的CurrencyManager对象。那怎样做到这点? 一个窗体上不仅会有多个控件(比如多个文本框)绑定到一个数据源,还可能出现多个控件绑定到多个数据源的情况(假设窗体中有两个DataSet,分别为两组控件提供数据,则在窗体中就会存在两个CurrencyManager对象),因此,再设计一个类用于管理这些CurrencyManager对象,这就是BindingContext类的功能。每个其上有数据绑定的窗体对象都至少会有一个BindingContext对象。 现在小结一下: 获取窗体的BindingContext对象à由BindingContext对象获取CurrencyManager对象à通过CurrencyManager对象以实现在记录集中移动的功能 这就是实现在数据集中移动功能的技术内幕。 说了这么多,其实在示例代码中只需要一句就行了:'数据绑定管理对象 Private cm As CurrencyManager '………… '获取数据绑定管理对象 cm = Me.BindingContext(ds1.Tables(0)) 自我探索:[/b] 一个容器控件比如Form、GroupBox和TabControl都可以有自己的BindingContext对象,以下代码设定了两个GroupBox的BindingContext对象: Dim bcG1 As New BindingContext() Dim bcG2 As New BindingContext() groupBox1.BindingContext = bcG1 groupBox2.BindingContext = bcG2 请设计一个应用程序,其上有两个GroupBox,每个GroupBox中都有一些数据绑定控件,编程实现这两组控件显示同一数据源中的不同位置的数据。
3 设计数据绑定辅助类
从前面介绍的内容可以看到,ADO.NET提供的数据绑定功能虽然灵活,但确实过于复杂而不好用了,而在数据集中移动的功能是非常常见的,如果在每一个窗体中都重复这些代码,实在是一件枯燥无聊的工作。因此,可以把这些代码封装起来,作为一个数据绑定辅助类。DataBindingHelper类就是出于这个目的而创建的。 首先定义一些类的成员变量: '内部绑定管理器 Private _cm As CurrencyManager = Nothing '内部的绑定控件容器,通常是窗体 Private _container As Control = Nothing '向外界表露CurrencyManager对象 Public ReadOnly Property cm() As CurrencyManager Get Return _cm End Get End Property '容器控件 Public Property container() As Control Get Return _container End Get Set(ByVal Value As Control) _container = Value End Set End Property 接着需要提供一个方法来指定数据源: '数据源属性,可以指定DataMember(对于DataSet),也可省略,对于DataTable Public Sub setDataSource(ByVal datasource As Object, Optional ByVal dataMember As String = Nothing) If _container Is Nothing Then MsgBox("请先指定控件容器") Exit Sub End If If dataMember Is Nothing Then _cm = _container.BindingContext(datasource) Else _cm = _container.BindingContext(datasource, dataMember) End If End Sub 现在就可以实现移动功能了,以后移一条记录为例: Public Sub MoveNext() '_cm未创建或为空,均退出 If _cm Is Nothing Then Exit Sub End If If _cm.Count = 0 Then Exit Sub End If If _cm.Position < _cm.Count - 1 Then _cm.Position += 1 End If End Sub 有了DataBindingHelper类,实现在数据集中移动就非常简单了,以下是示例工程中的代码: Dim dbh1 As New DataBindingHelper'设定容器对象为窗体 dbh1.container = Me‘设定数据源 dbh1.setDataSource(ds1.Tables(0))移动代码如下:Private Sub btnMoveFirst1_Click(……) Handles btnMoveFirst1.Click dbh1.MoveFirst() End Sub Private Sub btnMovePrev_Click(……) Handles btnMovePrev.Click dbh1.MovePrev() End Sub 是不是非常简单?从这个小示例中相信您一定能体会到面向对象技术所带来的好处!Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=278461
相关文章推荐
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- ADO.NET的数据绑定机制剖析及其应用
- 简单的数据绑定和ADO.NET的应用
- ADO.NET的应用(一)---asp.net中DataGrid控件实现数据绑定
- ADO.net数据绑定
- ADO.NET Entity Framework 一个简单数据绑定例子
- .NET 4.0 - Winform Control - DataGridView 数据绑定(ADO.NET Entity Framework)
- 学习笔记--ado.net 数据绑定
- ADO.NET访问数据-(2) DataSet本地缓存与数据库的交互过程,以及应用
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 如何用C#和ADO.NET建立一个数据绑定网格(转载)