打印本文 打印本文 关闭窗口 关闭窗口
多层数据库开发十二:使用数据控件
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1538  更新时间:2009/4/23 18:30:21  文章录入:mintao  责任编辑:mintao
                                       第十二章 使用数据控件
  在数据库应用程序中,数据控件是经常要用到的。与前面介绍的数据集构件如TTable、TQuery、TStoredProc、TClientDataSet不同的是,数据控件都是可视的。也就是说,如果修改了这些构件的属性,能在窗体上马上反映出来。如果这些构件的Enabled属性设为True并且数据集的Active属性也设为True,在设计期就可以看到数据。
12.1 Delphi 4中有哪些数据控件
  在Delphi 4的IDE中,数据控件都位于构件选项板的“Data Controls”页上。下面简单介绍这些数据控件:
.TDBGrid以行和列组成的栅格显示数据。
.TDBNavigator用于对整个数据库的记录进行导航,如向前翻一个记录、向后翻一个记录、翻到第一个记录、翻到最后一个记录等。
.TDBText把字段的内容作为标签显示。
.TDBEdit以编辑框的形式显示一个字段的内容。
.TDBMemo以多行文本编辑器的形式显示备注字段的内容。
.TDBImage用于显示数据库中的图像字段。
.TDBListBox以列表框的形式显示数据。
.TDBComboBox以组合框的形式显示数据。
.TDBCheckBox以复选框的形式显示数据。
.TDBRadioGroup以单选框分组框的形式显示数据。
.TDBLookupListBox以列表框的形式显示这个表的Lookup表的数据。
.TDBLookupComboBox以组合框的形式显示这个表的Lookup表的数据。
.TDBRichEdit以RTF格式显示备注字段的内容。
.TDBCtrlGrid与TDBGrid相似,但每一个单元都可以分别设置属性。
.TDBChart以图表的形式显示数据库的数据,用法与TChart相似。
  上述数据控件在设计期具有数据感知的特点。如果正确设置了DataSource属性指定了一个数据源,马上就能看到数据,而不需要编译和运行程序。
12.2 数据控件的基本用法
  这一节介绍数据控件的基本用法,包括怎样指定一个数据源、怎样编辑和更新数据、怎样禁止和允许数据刷新。
12.2.1 指定一个数据源
  数据控件必须通过TDataSource构件连接数据集。TDataSource构件扮演的角色实际上就是数据控件与数据集之间的桥梁。
  首先,把一个数据集构件放到窗体或数据模块上,设置它的DatabaseName属性指定要访问的数据库,设置它的TableName属性指定要访问的表。
  接着,把一个TDataSource构件放到窗体或数据模块上,设置它的DataSet属性指定数据集。
  然后,把一个数据控件放到窗体上,设置它的DataSource属性指定TDataSource构件,而这个TDataSource构件的DataSet属性已经指定了一个数据集。
  最后,设置数据控件的DataField属性指定要显示的字段。不过,对于TDBGrid、TDBCtrlGrid和TDBNavigator构件来说,不需要设置DataField属性,因为这几个控件是以整个数据集为工作内容的。
12.2.2 编辑和更新数据
  除了TDBNavigator构件外,其他数据控件都是用来显示和编辑数据的。这里要介绍怎样编辑数据。
  要使用户能编辑数据,数据集必须进入dsEdit状态。如果TDataSource的AutoEdit属性设为False,用户不能直接编辑数据,除非程序调用Edit函数。
  要使用户能够在数据控件中修改数据,必须把数据控件的ReadOnly属性设为False。如果ReadOnly属性设为True,数据控件中显示的数据就是只读的。
  一般情况下,TDataSource构件的Enabled属性设为True。如果这个属性设为False,数据控件就无法显示数据,更不能修改数据。
  如果数据集构件的ReadOnly属性设为True,数据集就是只读的,用户在数据控件中所作的修改不能写到数据集中。
  除了TDBGrid构件外,当用户修改了一个字段的值,还需要把输入焦点移走,新的数据才写到数据集中。在移走输入焦点之前,用户随时可以按ESC键取消修改。
  在TDBGrid构件建立的栅格中,当用户修改了一个字段的值,还需要把输入焦点移到另一条记录上,新的数据才写到数据集中。
12.2.3 禁止和允许数据刷新
  当程序正在遍历整个数据集或者搜索一个特定的记录时,应当暂时禁止数据控件刷新数据,这样能加快遍历或搜索的速度,防止屏幕总是在闪烁。
  调用数据集的DisableControls可以暂时禁止连接这个数据集的数据控件刷新数据。DisableControls函数通常在循环操作前调用。等循环结束后,程序应当立即调用数据集构件的EnableControls函数重新允许刷新数据。
  为了确保最后总是能恢复刷新,建议采用Try...Finally结构。这样,即使在循环中出现异常,也可以保证总能调用EnableControls。
  下面的代码演示了怎样调用DisableControls和EnableControls函数:
CustTable.DisableControls;
Try
  CustTable.First;
  While not CustTable.EOF Do
  Begin
   ...
   CustTable.Next;
  End;
Finally
  CustTable.EnableControls;
End;
12.2.4 手动刷新数据
  调用数据集的Refresh可以读取数据集中最新的数据并刷新数据控件,这个功能在多用户环境尤其有用,因为其他用户有可能已改变了数据集中的数据。
  有时候,调用Refresh可能会导致意想不到的结果。例如,如果另一个用户已经删除了一条记录,调用Refresh后,这条记录将从数据控件中消失。
12.3 显示单个字段的数据控件
  有的数据控件以数据库的一个或几个字段作为工作内容,如TDBText和TDBEdit,而有的数据控件以整个数据集为工作内容,如TDBGrid和TDBNavigator。
  显示单个字段的数据控件往往是从一个标准的Windows控件演化而来的,例如,TDBEdit构件就可以认为是TEdit的数据感知版本。
  图12.1 用TDBText构件把数据作为标签显示
12.3.1 把数据作为标签显示
  TDBText构件是一个只读的数据控件,它非常类似于TLabel构件和TStaticText构件。TDBText构件能够把数据作为标签显示,用来标注其他控件。例如,可以用一个TDBText构件在鱼的图片下显示鱼的名称(Common_Name字段),如图12.1所示。
  TDBText构件需要指定一个字段。当用户使用导航器或其他手段浏览记录时,TDBText构件显示的数据将自动变化,因为TDBText构件总是显示当前记录的数据。例如,在图12.1中,当用户用鼠标单击栅格的滚杆两端的箭头时,鱼的图片将自动变化,鱼的名称也相应改变,这一切都不需要编程
  TDBText构件的AutoSize属性一般要设为True,这是因为字段的内容长度可能是不同的。如果AutoSize属性设为False,有些较长的内容可能会被截断。
12.3.2 显示和编辑数据
  TDBText构件只能显示数据,不能编辑数据。要既能显示数据,又能编辑数据,就要用到TDBEdit构件。TDBEdit可以认为是TEdit的数据感知(Data-Aware)版本。
  例如,有一个TDataSource构件叫CustomersSource,它的DataSet属性指向一个TTable构件叫CustomersTable。把一个TDBEdit构件放在窗体上,其DataSource属性设为CustomersSource,把它的DataField属性设为CustNo。这个TDBEdit构件马上就能显示CustNo字段的值。用户可以在编辑框中键入新的值。
12.3.3 显示和编辑多行文本
  TDBMemo构件是TMemo构件的数据感知版本,可以显示dBASE和Paradox数据库中备注字段的内容。
  与TDBEdit不同的是,TDBMemo能够以多行的形式显示文本,同时也允许用户键入多行文本。
  默认情况下,TDBMemo允许用户修改它显示的文本。如果不想让用户修改文本,只要把ReadOnly属性设为True即可。要允许用户在文本中插入一个制表符,应当把WantTabs属性设为True,否则,当用户按下Tab键,将把输入焦点移走,而不是插入制表符。
  要限制用户最多可输入的字符数,可以设置MaxLength属性。如果这个属性设为0,表示没有限制。
  此外,ScrollBars属性可以设置要不要加上滚动栏,WordWrap属性可以设置是否允许自动绕回,Alignment属性可以设置文本的对齐方式。
  在运行期,您可以调用CutToClipboard和CopyToClipboard函数把选择的文本剪切和复制到剪贴板中,调用PasteFromClipboard能够粘贴剪贴板中的文本。如果AutoDisplay属性设为True,当DataField属性所指定的字段的内容改变了时,TDBMemo构件会自动刷新。如果AutoDisplay属性设为False,TDBMemo 构件上只显示字段名,用户必须双击这个构件或程序调用LoadMemo才能刷新数据。
12.3.4 以RTF格式显示文本
  TDBRichEdit构件可以认为是TRichEdit构件的数据感知版本,用于以RTF格式显示BLOB字段中的格式化文本。它的用法类似于TDBMemo构件,也能显示多行文本。
  注意:尽管TDBRichEdit构件能够显示RTF格式的文本,并且提供了很强的编辑功能,但是,它本身并没有提供用户界面,应用程序必须设计出相应的用户界面,才能把TDBRichEdit 构件强大的功能发挥出来。
  默认情况下,TDBRichEdit构件允许用户键入新的文本。如果不想让用户修改文本,可以把ReadOnly属性设为True。
  要允许用户在文本中插入一个制表符,应当把WantTabs属性设为True,否则,当用户按下Tab键,将把输入焦点移走,而不是插入制表符。
  要限制用户最多可输入的字符数,可以设置MaxLength属性。如果这个属性设为0,表示没有限制。
  如果AutoDisplay属性设为True,当DataField属性所指定的字段的内容改变了时,TDBRichEdit构件会自动刷新。如果AutoDisplay属性设为False,TDBRichEdit构件上只显示字段名,用户必须双击这个构件或程序调用LoadMemo函数才能刷新数据。
12.3.5 显示和编辑图像
  TDBImage构件可以认为是TImage构件的数据感知版本,它可以显示BLOB字段的内容。TDBImage构件从数据集中检索了图像后,在本地以DIB格式建立一个副本。
  可以调用CutToClipboard或CopyToClipboard函数把图像剪切或复制到剪贴板中,调用 PasteFromClipboard可以从剪贴板中粘贴图像。
  如果Stretch属性设为True,图像将自动缩放,以适应TDBImage构件的大小,这样就可能造成图像变形。如果AutoDisplay属性设为True,当DataField属性所指定的字段的内容改变了时,TDBImage构件会自动刷新。如果这个属性设为False,TDBImage构件上只显示字段名,用户必须双击这个构件才能刷新数据,当然也可以调用LoadPicture来刷新数据。
12.4 用列表框和组合框显示和编辑数据
  有4个特殊的数据控件可以用列表框和组合框显示和编辑数据,它们可以认为是标准的列表框和组合框的数据感知版本。下面简单介绍这4个数据控件:
.TDBListBox用列表框显示一组数据,让用户从中选择一个值。
.TDBComboBox用组合框显示一组数据,让用户从中选择一个值。
.TDBLookupListBox用列表框显示另一个数据集中的一组数据,让用户从中选择一个值。
.TDBLookupComboBox用组合框显示另一个数据集中的一组数据,让用户从中选择一个值。
12.4.1 TDBListBox
  TDBListBox构件能够用列表框显示一组数据,用户可以从中选择一个数据。当用户浏览记录时,程序将自动在列表框中搜索与字段的值匹配的项,如果找到就选择这一项,如图12.2所示。
  在列表框中选择匹配的项反过来,当用户在列表框中选择了某个项,程序就自动把当前记录的该字段的值改为列表框中选择的值。当然,要使修改有效还必须调用Post函数。
  要在设计期设置列表框中显示的项,可以单击Items属性边上的省略号按钮打开一个字符串列表编辑器,然后输入一些字符串。
  如果IntegralHeight属性设为True,列表框的高度将总是项的高度的整数倍。
12.4.2 TDBComboBox
  TDBComboBox构件实际上是TComboBox构件的数据感知版本,它能以组合框的形式显示一组数据,让用户从列表中选择一个值或直接输入一个值。
  Items属性用于设置列表中要显示的一组数据。在设计期,可以单击Items属性边上的省略号按钮打开一个字符串列表编辑器,然后输入一些字符串。
  DropDownCount属性用于设置当用户下拉组合框时不需要加滚动栏就能显示的项的个数,默认是8,表示用户下拉组合框时如果项的个数超过8个才加上滚动栏。如果实际的项数还没有DropDownCount属性指定的值多,下拉的组合框的高度自动缩小。
  在Style属性设为csOwnerDrawFixed的情况下,ItemHeight属性用于设置项的高度。
12.4.3 显示另一个数据集中的数据
  TDBLookupListBox构件和TDBLookupComboBox构件分别以列表框和组合框的形式显示另一个数据集中的数据。
  假设有一个表格叫OrdersTable,其中包含一个CustNo字段,用于表达客户的编号,但OrdersTable表中除了客户的编号外,不包含客户的其他信息。而另一个表格假设叫CustomersTable,除了有CustNo字段外,还有诸如客户的公司名称、地址等信息。
  TDBLookupListBox构件可以实现这样的功能,当用户在OrdersTable中浏览记录时,程序首先在CustomersTable中查找与CustNo字段匹配的记录,如果找不到,就从列表中查找与Company字段匹配的字符串;如果找到,就选择这一项,如图12.3所示。
  图12.3 TDBLookupListBox构件的用法
  当用户在列表中选择了一项,程序就在CustomersTable中查找与字符串匹配的Company字段,如果找到,就用CustNo字段的值替换OrdersTable表中的CustNo字段。
12.5 用复选框处理布尔类型的字段
   TDBCheckBox构件可以认为是TCheckBox构件的数据感知版本,用于处理布尔类型的字段。例如,可以用一个复选框来表示客户是否已付帐。
   TDBCheckBox构件实际上是把字段的值与预设的两个字符串比较,这两个字符串分别由ValueChecked和ValueUnChecked属性指定。如果字段的值与ValueChecked属性指定的字符串匹配,就选中复选框。如果字段的值与ValueUnchecked属性指定的字符串匹配,就不选中复选框。注意:ValueChecked属性和ValueUnchecked属性所指定的字符串不能相同。
  一般情况下,ValueChecked属性设为“True”、“Yes”之类的字符串,但也可以是其他任意的字符串,甚至是一组字符串,彼此之间要用分号隔开,例如:
  DBCheckBox1.ValueChecked := ''''True;Yes;On'''';
  上述情况下,当字段的值只要与其中一个字符串匹配,就选中复选框。要说明的是,ValueChecked属性指定的字符串是大小写敏感的。
  一般情况下,ValueUnchecked属性设为“False”、“No”之类的字符串,但也可以是其他任意的字符串,甚至是一组字符串,彼此之间用分号隔开。
  如果字段的值既不与ValueChecked属性指定的字符串匹配,也不与ValueUnchecked属性指定的字符串匹配,复选框就变灰。
12.6 用单选分组框限制字段的值
   TDBRadioGroup构件可以认为是TRadioGroup构件的数据感知版本,它可以限制用户从一组数据中选择字段的值。
   与TRadioGroup构件一样,首先要设置Items属性指定单选分组框中要显示哪些项。Items属性是一个典型的TStrings对象,每一个字符串对应着单选分组框中的一个按钮。
  当用户浏览记录时,如果字段的值与单选分组框中的某个按钮的标签匹配,就选择这个按钮,如图12.4所示。
  图12.4 选择与CustNo字段的值匹配的单选框
  反过来,当用户在单选分组框中选择一个按钮,程序就用这个按钮的标签赋值给DataField属性指定的字段。
  如果不想使按钮的标签与字段的值匹配,可以另外指定其他字符串,这就要用到Values属性。Values属性也是一个TStrings对象,用于指定一组字符串。当用户在单选分组框中选择一个按钮,程序就用Values属性中的一个字符串赋值给DataField属性指定的字段,而不是按钮的标签。
12.7 使用TDBGridTDBGrid构件
  以栅格的形式显示和编辑数据集中的数据。它的外观很大程度上取决于下面三个因素:
.一是永久的列对象。
.二是永久的字段对象。
.三是数据集构件的ObjectView属性将影响ADT和数组字段的显示方式。
  对于TDBGrid构件来说,最重要的属性是Columns,这是一个TDBGridColumns对象,用于管理一组TColumn对象。在设计期,可以打开一个编辑器建立永久的列对象,然后在对象观察器中设置列对象的属性。
12.7.1动态的列对象
  如果TDBGridColumns的State属性设为csDefault,列是动态生成的,列的属性取决于字段的属性。当字段的属性发生变化时,列的属性也跟着变化。
  让列动态生成的好处是,可以在运行期动态地选择其他数据集,而不用担心栅格是否适合于显示新的数据集。例如,可以用同一个TDBGrid构件先显示一个Paradox表,再显示查询另一个数据库的结果。
  在设计期,无法直接修改动态列对象的属性,只能修改字段对象的属性,从而间接地修改动态列对象的属性。
  动态列对象的生存期也取决于字段对象的生存期。如果数据集没有建立永久的字段对象,那么,当数据集关闭时,所有的动态列对象也将消失。
  注意:如果在运行期把TDBGridColumns的State属性设为csDefault,将删除所有的列对象,然后根据数据集中的字段对象重建列对象。
12.7.2 永久的列对象
  要能够在设计期自定义栅格,就要用到永久的列对象。建立了永久的列对象后,如果TDBGridColumns的State属性设为csCustomized,就可以独立设置每一列的属性。例如,默认情况下,列的标题显示字段的标签即DisplayLabel属性,通过修改TColumnTitle的Caption属性可以重新指定列的标题,而TField的DisplayLabel属性则不会受到影响。
  TDBGridColumns的State属性设为csCustomized适合于那些数据集的结构是固定不变的情况。如果需要在运行期切换不同的数据集,就不能把State属性设为csCustomized。
  要创建永久的列对象,首先要在窗体上选择TDBGrid构件,然后对象观察器中单击Columns属性边上的省略号按钮将打开如图12.5所示的编辑器。
  图12.5 创建永久的列对象
  刚开始的时候,这个编辑器是空白的,这是因为,默认情况下,栅格中的列对象都是动态生成的,还没有永久的列对象。
  要基于数据集中的每一个字段分别创建一个永久的列对象,可以单击鼠标右键,在弹出的菜单中选择“Add All Fields”命令。
  要创建一个独立的永久列对象,可以单击工具栏上的(Add New)按钮。选择这个刚创建的列对象,然后在对象观察器中设置FieldName属性指定一个字段,设置Caption属性指定列的标题。
  要删除一个列对象,可以单击工具栏上的(Delete Selected)按钮。如果把永久的列都删掉,栅格反而能显示数据集中所有的字段,这是因为,永久的列删掉以后,Delphi 4会自动把TDBGridColumns的State属性设为csDefault并且动态生成所有的列。  要调整列在栅格中显示的顺序,可以用鼠标把列对象前移或后移。
  对于永久的列对象来说,它的属性的默认值仍然取自于字段,除非您修改了永久列对象的属性。例如,默认的情况下,列的标题就是字段的DisplayLabel属性。如果修改字段的DisplayLabel属性,列的标题将随之改变。但是,一旦您修改了列对象的Ca

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口