打印本文 打印本文 关闭窗口 关闭窗口
多层数据库开发十二:使用数据控件
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1538  更新时间:2009/4/23 18:30:21  文章录入:mintao  责任编辑:mintao
ption属性,列的标题不再与字段的DisplayLabel属性存在联动关系,它们彼此是独立的。
  前面讲过,创建一个永久的列对象时,需要设置FieldName属性指定一个字段。不过,您也可以让FieldName属性为空,此时,TColumn对象的Field属性将返回NULL,并且该列在栅格中是空白的。空白的列往往用于用户显示一些自定义的内容,如图像或图表等。
  几个列对象的FieldName属性可以设为同一个字段。由此可见,TDBGrid的FieldCount属性可能小于栅格的列数
12.7.3 让用户编辑数据
  对于永久的列对象来说,可以提供几种方式让用户编辑数据。一是以组合框的方式显示另一个数据集的数据,二是建立一个静态的列表,三是用省略号按钮打开一个对话框。
  要以组合框的方式显示另一个数据集的数据,首先必须在数据集中增加一个Lookup字段,然后创建一个永久的列对象,设置它的FieldName属性指定这个Lookup字段,并且把它的ButtonStyle属性设为cbsAuto。经过上述操作后,栅格的效果如图12.6所示。
  图12.6 以组合框的形式显示另一个数据集的数据
  要建立一个静态的列表,不必事先增加一个Lookup字段,只要先创建一个永久的列对象,把ButtonStyle属性设为cbsAuto,在对象观察器中单击Picklist属性边上的省略号按钮打开一个字符串列表编辑器,然后依次键入一些字符串。
  要用一个对话框让用户选择数据,必须把列对象的ButtonStyle属性设为cbsEllipsis。当程序运行时,该列将出现一个省略号按钮,单击这个省略号按钮将触发OnEditButtonClick事件,在处理这个事件的句柄中可以打开一个对话框,让用户选择数据。对于图像字段来说,当用户单击省略号按钮时,可以显示一个图像。
12.7.4 在设计期设置列对象的属性
  列对象的属性决定了数据在栅格中的显示方式。在设计期,可以设置它的下列属性:
.Alignment用于设置数据的对齐方式,默认值是TField的Alignment。
.ButtonStyle设为cbsAuto表示加上一个组合框。设为cbsEllipsis表示加上一个省略号按钮,当用户单击此按钮将触发OnEditButtonClick。设为cbsNone表示既没有组合框也没有省略号按钮。
.Color用于设置背景颜色,默认值是TDBGrid的Color。
.DropDownRows 下拉列表框中的项数,默认值是7。
.Expanded如果列对象所对应的字段是ADT或数组字段,这个属性用于控制是否展开。l FieldName用于指定一个字段,可以让它空着。
.ReadOnly设为True表示该列是只读的,不能编辑。
.Width用于设置列的宽度,默认值是TField的DisplayWidth。
.Font用于设置该列中字符的字体,默认值是TDBGrid的Font。
.PickList用于建立一个静态的列表。
.Title这是个TColumnTitle对象,用于设置列的标题。
  其中,TColumnTitle具有下列属性:
.Alignment用于设置标题的对齐方式,设为taLeftJustify表示左对齐,设为taCenter表示居中,设为taRightJustify表示右对齐。
.Caption用于指定标题的文字,默认值是TField的DisplayLabel。
.Color用于设置标题的背景颜色,默认值是TDBGrid的FixedColor。
.Font用于设置标题的字体,默认值是TDBGrid的TitleFont。
12.7.5 显示ADT和数组字段的值
  Delphi 4的TDBGrid构件完全支持Oracle 8的对象字段。
  如果数据集构件的ObjectView属性设为True,对象字段就可以展开或折叠。当对象字段展开的时候,原来的一列就分为若干列,每一列显示一个子字段的值,每一个子字段所在的列都有自己的标题栏,这样可以明显地看出字段之间的包含关系。当对象字段折叠的时候,就只显示一个字符串,该字符串列出了每个子字段的值,彼此之间用逗号隔开。
  如果数据集构件的ObjectView属性设为False,每个子字段与对象字段一样,都单独占一列。
  下面介绍几个与对象字段有关的属性。一是TColumn的Expandable属性,如果设为True,表示该列是可展开的。二是TColumn的Expanded属性,用于测试列当前是否已展开。三是TDBGrid的MaxTitleRows属性,用于设置栅格中最多可出现几行标题。四是TDataSet的ObjectView,这个属性前面已介绍过了。五是TColumn的ParentColumn属性,用于返回显示父字段的列对象。
   图12.7演示了ObjectView属性设为False的情况:
   图12.7 ObjectView属性设为False的情况
   图12.8演示了ObjectView属性设为True但对象字段被折叠的情况:
   图12.8 ObjectView属性设为True但对象字段被折叠的情况
   图12.9演示了ObjectView属性设为True但对象字段被展开的情况:
   图12.9 ObjectView属性设为True但对象字段被展开的情况
12.7.6 设置栅格的选项
  可以在设计期设置栅格的选项,这就要用到TDBGrid构件的Options属性。Options属性是一个集合,可以包含下列元素:
.dgEditing如果包含这个元素(下同),允许用户修改栅格中的数据;
.dgAlwaysShowEditor栅格自动处于编辑状态,否则需按F2才进入编辑状态;
.dgTitles显示列的标题;
.dgIndicator当前行的最左端将显示一个4符号;
.dgColumnResize列的宽度可以重设;
.dgColLines列与列之间用线分开;
.dgRowLines行与行之间用线分开;
.dgTabs可以用Tab键和Shift+Tab键在列与列之间移动输入焦点;
.dgRowSelect用户可以选择一整行,否则就只能选择一个单元;
.dgAlwaysShowSelection即使输入焦点移走,选择的单元仍然保持选择状态;
.dgConfirmDelete按Ctrl+Delete删除一行时将显示一个确认框,让用户确认;
.dgCancelOnExit在栅格退出的时候,任何未决的修改将被取消
.dgMultiSelect用户可以在栅格中选择多行,相当于一个复选的列表框。
12.7.7 在运行期响应用户的动作
  TDBGrid构件具有几个事件,用于响应用户的动作。由于栅格是由行和列构成的,因此,在事件句柄中,首先要区分当前是在哪一列上。下面列出了这些事件:
.OnCellClick当用户单击一个单元时将触发这个事件。
.OnColEnter当输入焦点进入某一列时将触发这个事件。
.OnColExit当输入焦点离开某一列时将触发这个事件。
.OnColumnMoved当用户把某一列移到另一个位置时将触发这个事件。
.OnDblClick当用户在栅格中双击时将触发这个事件。
.OnDragDrop当用户在栅格中释放被拖曳的对象时将触发这个事件。
.OnDragOver当用户拖着一个对象经过栅格时将触发这个事件。
.OnDrawColumnCell当某个单元需要重画时将触发这个事件。
.OnDrawDataCell 在State属性设为csDefault的情况下,当某个单元需要重画时将触发这个事件。
.OnEditButtonClick当用户单击省略号按钮时将触发这个事件。
.OnEndDrag当用户释放了鼠标时将触发这个事件。
.OnEnter当栅格得到输入焦点时将触发这个事件。
.OnExit当栅格失去输入焦点时将触发这个事件。
.OnKeyDown当用户按下一个键时将触发这个事件。
.OnKeyPress当用户按下一个可见的字符键时将触发这个事件。
.OnKeyUp当用户释放一个键时将触发这个事件。
.OnStartDrag当用户开始进行拖放操作时将触发这个事件。
.OnTitleClick当用户单击某一列的标题时将触发这个事件。
12.7.8 一个特殊的数据库栅格
  TDBGrid构件的特点是一行只显示一个记录,但可以设置每一列的属性。 TDBCtrlGrid构件的特点是每一行都是一个窗格(TPanel对象),可以在窗格上放一些控件。例如,可以把一个TDBEdit构件放到窗格上,让它显示某个字段的值,还可以在编辑框的旁边加一个TLabel构件作为标签。TDBCtrlGrid的另一个特点是一行上可以有多个窗格,也就是说,一行可以显示多个记录,窗格的高度和宽度都是可以调整的。
  首先,要把一个TDBCtrlGrid构件放到窗体上,设置它的DataSource属性指定一个TDataSource构件。刚开始的时候,TDBCtrlGrid构件有三行和一列。
  接着,要把一些数据控件放到TDBCtrlGrid构件的“设计单元”上,设置这些数据控件的DataField属性指定要显示的字段。
  “设计单元”通常是最上边或最左边的那个单元,与其他单元在外观上的区别是它没有斜线底纹。
  注意:只能把数据控件放到TDBCtrlGrid构件的“设计单元”上,当程序编译运行后,会自动把“设计单元”上的数据控件复制到其他单元,每个单元显示不同的记录。
  图12.10演示了TDBCtrlGrid构件的用法:
  图12.10 TDBCtrlGrid构件的用法
  下面列出了TDBCtrlGrid构件的属性:
.AllowDelete设为True表示允许删除记录。
.AllowInsert设为True表示允许插入记录。
.ColCount用于设置每一行的窗格数,默认是1。
.Orientation设为goVertical表示从上到下显示记录,设为goHorizontal表示从左到右显示记录。
.PanelHeight用于设置窗格的高度,默认是72。
.PanelWidth用于设置窗格的宽度,默认是200。
.RowCount用于设置行数,默认是3。
.ShowFocus如果设为True,显示当前记录的窗格上有一个虚线边框。
.SelectedColor用于设置显示当前记录的窗格的背景颜色。
12.8 导 航 器
  导航器是用TDBNavigator构件实现的,它可以让用户方便地浏览和操纵记录。导航器最多可由10个按钮组成,包括:
.First第一个记录;
.Prior前一个记录;
.Next后一个记录;
.Last最后一个记录;
.Insert插入一个空白的记录;
.Delete删除当前记录;
.Edit允许编辑当前记录;
.Post使未决的编辑操作有效;
.Cancel取消未决的编辑操作;
.Refresh用数据集中的最新的数据刷新记录。
  可以根据需要,在导航器上有选择地显示部分按钮,这就要用到VisibleButtons属性。
  在设计期,可以在对象观察器中选择要显示在导航器上的按钮。在运行期,您可以通过编程选择要显示在导航器上的按钮。例如,假设要用同一个导航器为两个数据集导航,其中一个允许用户编辑数据,另一个不允许用户编辑数据。当在两个数据集之间切换时,应当动态地改变导航器上的按钮,因为对于不允许用户编辑数据的数据集来说,导航器上不应当出现Insert、Delete、Edit、Post、Cancel和Refresh等按钮。下面代码把这些按钮隐藏:
Procedure TForm1.CustomerCompanyEnter(Sender :TObject);
Begin
If Sender = CustomerCompany then
Begin
DBNavigatorAll.DataSource := CustomerCompany.DataSource;
DBNavigatorAll.VisibleButtons := [nbFirst,nbPrior,nbNext,nbLast];
End
Else
Begin
DBNavigatorAll.DataSource := OrderNum.DataSource;
DBNavigatorAll.VisibleButtons := DBNavigatorAll.VisibleButtons + [nbInsert,nbDelete,nbEdit,nbPost,nbCancel,nbRefresh];
End;
End;
  这里顺便说一下,当同一个导航器需要为几个数据集导航时,就要动态地设置DataSource属性。假设窗体上有两个TDataSource构件,分别叫CustomersSource和OrdersSource,它们的DataSet属性分别指定CustomersTable表和OrdersTable表,另外,窗体上有两个TDBEdit构件,分别叫CustomersEdit和OrdersEdit,它们的DataSource属性分别指向CustomersSource和OrdersSource。下面这段程序为这两个TDBEdit构件写了一个公共的事件句柄来处理OnEnter事件,当用户在CustomersEdit 上编辑时,导航器将为CustomersTable导航,当用户在OrdersEdit上编辑时,导航器将为OrdersTable导航。
Procedure TForm1. CustomerEditEnter(Sender: TObject);
Begin
If Sender = CustomerEdit Then
   DBNavigatorl.DataSource := CustomerEdit.DataSource;
Else
DBNavigator1.DataSource := OrderEdit.DataSource;
End;
12.9 数 据 源
  TDataSource构件是一个非可视的构件,它充当了数据集和数据控件之间的桥梁。每一个数据控件都必须指定一个数据源(TDataSource构件),相应地,TDataSource构件的DataSet属性必须指定一个数据集。下面简单介绍一下TDataSource构件的属性和事件。
  DataSet属性用于指定一个数据集。在设计期,可以在对象观察器中为DataSet属性选择一个数据集。在运行期,可以通过代码动态地选择数据集。程序示例如下:
With CustSource Do
Begin
If DataSet = ''''Customers'''' then
DataSet := ''''Orders''''
Else
DataSet := ''''Customers'''';
End;
  也可以指定另一个窗体上的数据集构件,例如:
Procedure TForm2. FormCreate (Sender : TObject);
Begin
DataSource1.Dataset := Form1.Table1;
End;
  一般情况下,TDataSource构件的名称是无关紧要的。不过,TDataSource构件的名称应当能反映它所连接的数据集,例如,假设TDataSource构件连接的数据集叫Customers,相应地,TDataSource构件的名称最好叫CustomersSource。
  Enabled属性用于控制TDataSource构件是否与数据集连接,设为True表示连接,设为False表示暂时断开连接。如果Enabled属性设为False,凡是连接于这个数据源的数据控件将变成空白。
  如果AutoEdit属性设为True,当用户在数据控件中键入字符时,数据集就自动进入dsEdit状态。如果AutoEdit属性设为False,程序必须调用Edit函数才能进入dsEdit状态。
  当数据集的当前记录的位置发生变化时将触发OnDataChange事件,这可能是因为程序调用了Next、Previous、Insert等方法。
  当前记录的数据将要被更新时将触发OnUpdateData事件,这可能是因为调用了Post。在处理这个事件的句柄中,可以对数据进行校验。
  当State属性发生变化时将触发OnStateChange事件。例如,可以用一个标签动态地显示当前的状态。程序示例如下:
ProcedureTForm1.DataSource1.StateChange(Sender:TObject);
var
S:String;
Begin
Case CustTable.State of
dsInactive: S := ''''Inactive'''';
dsBrowse: S := ''''Browse'''';
dsEdit: S := ''''Edit'''';
dsInsert: S := ''''Insert'''';
dsSetKey: S := ''''SetKey'''';
End;
CustTableStateLabel.Caption := S;
End;
  利用OnStateChange事件也可以动态地允许或禁止按钮和菜单项,程序示例如下:
Procedure Form1.DataSource1.StateChange(Sender: TObject);
Begin
CustTableEditBtn.Enabled := (CustTable.State = dsBrowse);
CustTableCancelBtn.Enabled := CustTable.State in [dsInsert, dsEdit, dsSetKey];
...
End;

上一页  [1] [2] 

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