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] |