`
wodamazi
  • 浏览: 1419605 次
文章分类
社区版块
存档分类
最新评论

ADO.NET的数据绑定机制剖析及其应用

 
阅读更多

这是我写的书的一部分,全部原创,刚完成,欢迎提出意见。

bitfan

-------------------------------------------------------

7.5.2 在数据集中移动

当在程序中需要显示多条记录时,我们往往希望能给记录一个“记录号”以方便定位记录,比如:“到第一条”,“到最后一条”,“跳到第100条”……。

DataTable中的记录(即DataRow)本身并没有一个所谓的“记录号”,DataTable本身也没有提供这种功能。

提示:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

在VB6中,记录集对象RecordSet提供MoveFirst,MoveLast等定位功能。这是由ADO实现的。在ADO.NET中,DataTable和DataRow都没有这些方法。

乍看起来,不能在数据集中移动,好象是ADO.NET设计的一个疏漏。事实上,ADO.NET把所有在数据集中定位的功能全部抽取出来,再加上其他一些功能,构建了ADO.NET的数据绑定机制,与原来ADO所提供的有限定位功能相比,ADO.NET更为强大而灵活。

请试着运行本书配套光盘中的示例MoveInDataTable,其运行界面如715

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><font size="4"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></font></shapetype>



715
数据绑定示例

这个程序在运行时,既可以点击右下方的四个按钮,也可以直接点击上部的网格在数据集中移动,当前行的内容同步在下半部的两个文本框中显示。可以在文本框中直接修改数据,当移动到其它行时,网格中的记录同步刷新。

通过这个示例,我们来剖析ADO.NET中数据绑定机制的原理。

1 什么叫数据绑定?

所谓数据绑定,通俗地说,就是把数据源(如DataTable)中的数据取出来,显示在窗体的各种控件上,用户可以通过这些控件查看和修改数据,这些修改会自动地保存到数据源中,参见716


716
数据绑定原理

Windows 窗体可以利用两种类型的数据绑定:简单绑定和复杂绑定。这两种类型具有不同的优点。

l 简单绑定

简单数据绑定指将一个控件绑定到单个数据元素(如数据集表的列中的值)的能力。这是用于 TextBox 控件或 Label 控件等控件(即通常只显示单个值的控件)的典型绑定类型。 715中的两个文本框,分别绑定到了DataTable中的“AddressStr”和“ClientName”两个字段。

l 复杂绑定

复杂数据绑定指将一个控件绑定到多个数据元素的能力,通常绑定到数据库中的多条记录。 715中的DataGrid就绑定到了一个DataTable,它可以一次显示多条记录和多个字段的值。

2 实现在数据集中移动

在数据集中移动是数据绑定机制中的一个子功能。

为了方便理解ADO.NET中复杂的数据绑定机制,我们先在MoveInDataTable示例中的一个简单的窗体内实现数据移动功能,参见717


717
手动实现在记录集中移动

下面对代码进行分析

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

在示例程序的第二窗体(参见715)中,只不过是多了将文本框绑定到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绑定。

文本框绑定的第三个参数被称为“绑定字串”,以英文句点隔开,其格式为:

表名.字段名

其特点是越左边的子字串其范围就越大。

技术内幕:

其实数据绑定不仅限于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的数据绑定机制主要由以下类构成:


718
数据绑定类

718以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))

自我探索:

一个容器控件比如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

是不是非常简单?

从这个小示例中相信您一定能体会到面向对象技术所带来的好处!

分享到:
评论

相关推荐

    ADO.NET本质论.pdf

    书中深入剖析了ado.net的本质,探索了类、接口、属性和方法的工作原理,同时还为其他数据访问api(包括oledb,ado,odbc和jdbc)的程序员,提供了有价值的参考材料。本书适合具有一定数据库基础的开发人员阅读,也可...

    ADO.NET 2.0技术内幕(高清 中文 带书签 全)

    本书介绍了如何用ADO.NET 2.0对独立应用、企业级应用和Web应用程序中的数据进行访问、排序和操作。作者针对如何利用Visual Studio 2005中的新工具和向导,编写、测试并调试数据库应用程序代码,用丰富的示例代码、...

    ADO.NET数据库访问技术案例教程光盘

    介绍了ADO.NET主要对象的基本概念和使用方法,着重探讨了Windows程序和Web程序中数据的浏览、搜索、添加、修改、删除、统计与输出等功能的实现方法,介绍了数据验证、数据绑定、记录导航、参数设置、报表设计等技术...

    ADO.NET数据库访问技术案例教程湖南省教育科学“十一五” 规划重点资助课题研究成果教材)

    第4章-ADO.NET的数据库访问对象.ppt 第5章-统计数据源中的数据.ppt 第6章-浏览数据源中的数据.ppt 第7章-更新数据源中的数据.ppt 第8章-数据验证与容错处理.ppt 第9章-对数据库和数据表的操作.ppt 第10章-数据绑定与...

    剖析ADO.NET批处理更新

    ADO.NET应用程序和基础数据源之间的交互基于一个具有双向信道的双体系结构。您可以使用各个特定于提供程序的命令或批处理更新过程来访问数据源,以读取和写入行。在这两种情况下,数据访问都会产生完全双向绑定,并...

    剖析ADO.NET批处理更新(深入研究数据访问)

    ADO.NET应用程序和基础数据源之间的交互基于一个具有双向信道的双体系结构。您可以使用各个特定于提供程序的命令或批处理更新过程来访问数据源,以读取和写入行。在这两种情况下,数据访问都会产生完全双向绑定,并...

    亮剑.net图改asp.net网站开发实战源码.rar

     ADO.NET类与断线数据集DataSet剖析,ADO.NET与ASP.NET网页整合应用实例,多层式架构组成探讨,业务逻辑层类设计,类图表的建立与设计说明,ObjectDataSource数据控制项类绑定设计,主版页、HTML元素、CSS与表示层...

    北京中科信软 Visual Basic.NET培训

    ADO.NET中的数据更新 多活动结果集 批量复制 ADO.NET中的异步处理 事务处理机制 LINQ 案例分析:采用N层架构和分布式的大型图书系统 四 Web应用(ASP.NET&XML; WebService ASP.NET 页面控制机制及编译模型,...

    C#与.NET3.5高级程序设计(第4版) 中文4

    22.2 ADO.NET的数据提供程序 581 22.3 其他的ADO.NET命名空间 584 22.4 System.Data命名空间的类型 584 22.5 使用接口抽象数据提供程序 588 22.6 创建AutoLot数据库 590 22.7 ADO.NET 数据提供程序工厂...

    21 天学通ASP.NET(包含源码)

    第二篇重点分析了ASP.NET数据开发的内容,主要包括数据库开发入门、SQL语言、ADO.NET对数据库访问、数据绑定控件、LINQ to SQL数据开发和使用水晶报表。第三篇主要分析了ASP.NET高级应用的内容,包括角色及成员资格...

    21天学通ASP.NET源代码

    第二篇重点分析了ASP.NET数据开发的内容,主要包括数据库开发入门、SQL语言、ADO.NET对数据库访问、数据绑定控件、LINQ to SQL数据开发和使用水晶报表。第三篇主要分析了ASP.NET高级应用的内容,包括角色及成员资格...

    21天学通ASP.NET源代码2

    第二篇重点分析了ASP.NET数据开发的内容,主要包括数据库开发入门、SQL语言、ADO.NET对数据库访问、数据绑定控件、LINQ to SQL数据开发和使用水晶报表。第三篇主要分析了ASP.NET高级应用的内容,包括角色及成员资格...

    21天学通ASP.NET 光盘part02

    第二篇重点分析了ASP.NET数据开发的内容,主要包括数据库开发入门、SQL语言、ADO.NET对数据库访问、数据绑定控件、LINQ to SQL数据开发和使用水晶报表。第三篇主要分析了ASP.NET高级应用的内容,包括角色及成员资格...

    21天学通ASP.NET 光盘

    第二篇重点分析了ASP.NET数据开发的内容,主要包括数据库开发入门、SQL语言、ADO.NET对数据库访问、数据绑定控件、LINQ to SQL数据开发和使用水晶报表。第三篇主要分析了ASP.NET高级应用的内容,包括角色及成员资格...

    ASP.NET 数据库入门经典C#篇pdg

    ASP.NET 对如何开发复杂和交互的 Web 站点作了重大的改进, ADO.NET 提供了强大而灵活的数据访问功能,从根本上改变了从 Web 应用程序中检索、处理和存储数据的方式。 本书将介绍如何创建能够支持数据的 ASP.NET ...

    asp.net知识库

    ADO.NET 2.0 大批量数据操作和多个动态的结果集 ADO.NET 2.0 异步处理 在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+...

    ASP.NET4权威指南源代码下载

    第二部分详尽地讲解了ASP.NET访问的所有细节,包括数据管理、数据控件绑定与操作、GridView控件、LINQ查询、LINQ与ADO.NET和XML,以及ADO.NET实体框架等;第三部分深入浅出地讲解了开发一个Web站点必须掌握的各种...

    《ASP.NET 4 权威指南》pdf版

    查询、LINQ 与ADO.NET 和XML,以及ADO.NET 实体框架等;第三部分深入浅出地讲解了开发一个Web 站 点必须掌握的各种知识点、流程和方法;第四部分是本书的高级话题,分析了ASP.NET 状态管理、自定 义服务器控件、ASP...

Global site tag (gtag.js) - Google Analytics