第1章 数据库感知组件
所谓数据感知组件,就是指:能够自动显示数据库中记录内容的组件。它们可以从数据库中取得记录内容并显示,同时又可以将用户对记录的修改结果保存回数据库中。例如:前面我们经常使用的DBGrid组件。
数据感知组件通过与TDataSource组件的连接,进而取得数据源,并将它显示出来。DBGrid组件是一个二维形式的组件,因而它可以显示整个表的内容。而本章中将要介绍的数据感知组件,只能显示当前记录的某个字段值。这些数据感知组件位于组件面板的Data Controls 页中。
图 3‑1 Data Control组件面板上的数据感知组件
1.1 感知组件使用介绍
1.1.1 DBEdit:
DBEdit是最常用的数据感知构件之一,既可以显示字段内容,又可将用户的修改结果保存到数据库中,类似于Edit。
例3‑1显示表中记录,并将修改结果保存(或放弃)到数据库中
图 3‑2 用DBEdit显示表中数据
主要属性设置如下:
构件 |
属性 |
属性值 |
ADOTable1 |
ConnectionString |
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Delphi数据库程序设计\教材例子(光盘)\CH01\STUDENTS.mdb;Persist Security Info=False |
TableName |
STUDENTS |
|
Active |
True |
|
DataSource1 |
DataSet |
ADOTable1 |
DBEdit |
DataSource |
DataSource1 |
DataField |
姓名 |
<保存>按钮的OnClick事件处理程序:
procedure TForm1.Button1Click(Sender: TObject);
begin
if ADOTable1.Modified then
begin
ADOTable1.Post;
Showmessage('保存成功!');
end
else
showmessage('记录没有被修改,不能保存!');
end;
<放弃修改>按钮的OnClick事件处理程序:
procedure TForm1.Button2Click(Sender: TObject);
begin
ADOTable1.Cancel;
end;
1、 调用ADOTable的Post方法将修改结果保存到数据库中,有一个先决条件:ADOTable连接的表必须是处于编辑状态,否则调用Post方法将会出现错误。 2、 当用户在DBEdit中修改字段内容时,ADOTable所连接的表会自动进入编辑状态。 3、 要判断ADOTable是否处于编辑状态,只要读取ADOTable的Modified属性,当Modified为True时即为编辑状态。 |
有时,我们需要通过程序而不是通过用户界面的交互操作来实现记录的修改,又该如何处理呢?
例3‑2不显示表中记录,通过程序修改记录,并将修改结果保存到数据库中。
图 3‑3 通过执行程序来修改并保存记录
主要属性设置如下:
构件 |
属性 |
属性值 |
ADOTable1 |
ConnectionString |
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Delphi数据库程序设计\教材例子(光盘)\CH01\STUDENTS.mdb;Persist Security Info=False |
TableName |
STUDENTS |
|
Active |
True |
|
DataSource1 |
DataSet |
ADOTable1 |
DBNavigator1 |
DataSource |
DataSource1 |
在ADOTable1的AfterScroll事件中添加下列事件处理程序,用于显示当前记录号
procedure TForm1.ADOTable1AfterScroll(DataSet: TDataSet);
begin
Edit1.Text:=IntToStr(ADOTable1.RecNo);
end;
在Button1的OnClick事件中添加下列事件处理程序,用于修改当前记录的姓名字段值
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOTable1.Edit;
ADOTable1.FieldByName('姓名').AsString:='王小二'; //将姓名修改为“王小二”
ADOTable1.Post;
end;
1.1.2 DBText:
当只要显示而并不需要修改表中记录时,可以使用数据感知组件DBText,它类似于Label组件。
例3‑3利用DBText来显示表中记录。
图 3‑4 用DBText组件来显示表中数据
主要属性设置如下:
构件 |
属性 |
属性值 |
ADOTable1 |
ConnectionString |
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Delphi数据库程序设计\教材例子(光盘)\CH01\STUDENTS.mdb;Persist Security Info=False |
TableName |
STUDENTS |
|
Active |
True |
|
DataSource1 |
DataSet |
ADOTable1 |
DBText1 |
DataSource |
DataSource1 |
DataField |
姓名 |
|
DBText2 |
DataSource |
DataSource1 |
DataField |
住址 |
|
DBNavigator1 |
DataSource |
DataSource1 |
事件处理程序:不需要编写任何代码。
1.1.3 DBMemo
DBMemo与DBEdit类似,既可以显示、也可修改字段内容,但DBEdit只能显示单行文本,而Memo却可以显示多行文本,主要用于显示备注型字段的内容。
1.1.4 DBComboBox
有些字段值是一些固定的常量,如:性别字段只有“男”与“女”,职称字段一般是“教授”、“副教授”、“讲师”、“助教”等。对于这些字段,在用户录入或修改记录时,希望能从列表框中选择以减少文字录入的工作量,此时,我们可以使用DBComboBox来实现此目的。
例3‑4设计如下的数据维护(录入/修改)窗体。
图 3‑5 创建数据录入窗体
DBComboBox组件的属性设置如下:
构件 |
属性 |
属性值 |
DBComboBox |
DataSource |
DataSource1 |
DataField |
性别 |
|
Items |
男 女 |
上述例子中,DBComboBox 的Items属性必须设置为性别字段可能取到的值。 |
1.1.5 DBLookupComboBox
关系型数据库的表之间往往存在着一对多关系,如:Dept.mdb数据库中,“主管名单”表与“员工名单”表之间就存在着一对多的关系,其中的关联字段是“部门代号”。
在设计“员工名单”的数据录入窗体(见图 3‑6)时,对于“部门代号”字段,存在着一些问题:
一方面,直接在窗体中显示“部门代号”,很不直观;另一方面,很少有人会记住所有部门的“部门代号”,因而给用户输入带来困难。
我们知道:“员工名单”表中只有“部门代号”,并没有“部门名称”,“部门名称”在“主管名单”表中。
如何解决这一问题?这就要借助于DBLookupComboBox这个数据感知组件。
具体步骤如下:
(1)、首先在窗体上再添加一个ADOTable2与DataSource2,设置好ADOTable2的ConnectionString属性,并设置TableName属性为:“主管名单”,Active属性设置为True,DataSource2的DataSet属性设置为:ADOTable2
(2)、删除原来用于显示部门代码的那个DBEdit组件,在此位置放置一个DBLookupComboBox1。
(3)、设置DBLookupComboBox1的相关属性如下:(见图 3‑7)
构件 |
属性 |
属性值 |
DBLookupComboBox1 |
ListSource |
DataSource2 |
ListField |
部门名称 |
|
KeyField |
部门代码 |
|
DataField |
部门代码 |
|
DataSource |
DataSource1 |
图 3‑7 设置DBLookupComboBox1的相关属性
(4)、运行程序,即可看到结果。
程序运行时,我们从DBLookupComboBox1中看到的是“部门名称”,并且用户可以通过下拉列表选择不同的“部门名称”,但实际上保存到“员工名单”表中的却是“部门代号”,(见图 3‑8) 而这正是我们所希望的! |
在实际的数据库应用系统开发中,具有一对多关系的表是非常普遍的,上述的数据录入窗体也是常见的,所以利用DBLookupComboBox来实现数据录入的技巧必须熟练掌握。
1.1.6 DBCheckBox
DBCheckBox通常用于显示、修改逻辑型字段的值,如:婚否、是否党员、有无工作经历、是否已付帐等。
图 3‑9 用DBCheckBox显示表中逻辑型字段
DBCheckBox构件实际上是把字段的值与预设的两个字符串比较,这两个字符串分别由ValueChecked和ValueUnChecked属性指定。如果字段的值与ValueChecked属性指定的字符串匹配,就选中复选框。如果字段的值与ValueUnchecked属性指定的字符串匹配,就不选中复选框。注意:ValueChecked属性和ValueUnchecked属性所指定的字符串不能相同。
一般情况下,ValueChecked属性设为“True”、“Yes”之类的字符串,ValueUnchecked属性设为“False”、“No”之类的字符串,但也可以是其他任意的字符串,如:“是”、“否”;“已付款”、“未付款”等。
如果字段的值既不与ValueChecked属性指定的字符串匹配,也不与ValueUnchecked属性指定的字符串匹配,复选框就变灰。
1.1.7 DBRadioGroup
DBRadioGroup构件可以限制用户从一组数据中选择字段的值。与TRadioGroup构件一样,首先要设置Items属性指定单选分组框中要显示哪些项。Items属性是一个典型的TStrings对象,每一个字符串对应着单选分组框中的一个按钮。
当用户浏览记录时,如果字段的值与单选分组框中的某个按钮的标签匹配,就选择这个按钮;反过来,当用户在单选分组框中选择一个按钮,程序就用这个按钮的标签赋值给DataField属性指定的字段。
如果不想使按钮的标签与字段的值匹配,可以另外指定其他字符串,这就要用到Values属性。Values属性也是一个TStrings对象,用于指定一组字符串。当用户在单选分组框中选择一个按钮,程序就用Values属性中的一个字符串赋值给DataField属性指定的字段,而不是按钮的标签。
图 3‑10 用DBCheckBox显示表中逻辑型字段
1.1.8 DBImage
用于显示图片字段,类似于 Image构件。
1. Access数据库中存储图片
Access中具有“OLE对象”类型的字段能够存储各种文档、图片、声音及其它二进制数据。
图 3‑11 Access数据库中的OLE字段
2. 在Delphi中如何将图片保存到Access数据库中
方法一:
DBImage本身没有LoadFromFile方法,但有Picture属性,而Picture属性(也是一个对象)具有LoadFromFile方法,所以可以使用Picture属性的LoadFromFile方法来将图片添加到数据库中。
procedure TForm1.Button2Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin
ADOTable1.Edit;
DBImage1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
ADOTable1.Post;
end;
end;
方法二:
利用数据集构件的字段编辑器创建永久性字段,这些永久性字段都具有各自的类型,而对应于OLE字段的类型为:TBlobField 。TBlobField类型的字段具有LoadFromFile方法。
procedure TForm1.Button2Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin
ADOTable1.Edit;
ADOTable1pic.LoadFromFile(OpenPictureDialog1.FileName);
ADOTable1.Post;
end;
end;
这里,ADOTable1pic为图片字段(永久性字段)对象的名称。
如果不创建永久性字段,而是用ADOTable1.FieldByName(‘pic’)或ADOTable1.Fields[i]来引用字段对象,则需要强制类型转换: TBlobField (ADOTable1.FieldByName(‘pic’)).LoadFromFile(OpenPictureDialog1.FileName); |
方法三:
直接用复制/粘贴的办法,将图片粘贴到DBImage中。
3. 如何处理JPG格式图片
DBImage构件只能显示位图(Bmp文件)而无法显示JPG格式的图片。但位图的文件大小要比JPG文件大得多,不适合保存大量图片,所以尽可能使用JPG格式文件。
保存:采用上述三个方法之一。
显示:改用Image 构件(Image 构件能显示JPG图片)。但Image 构件不是数据感知构件,无法自动从数据库中读取记录内容,只能通过下面代码实现:
procedure TForm1.ADOTable1AfterScroll(DataSet: TDataSet);
var s:TMemoryStream;
begin
s:=TMemoryStream.Create;
ADOTable1DSDesigner7.SaveToStream(s);
Image1.Picture.Bitmap.LoadFromStream(s);
s.free;
end;
1.1.9 DBGrid
1 、动态的列对象
DBGrid由列(对象类型为TColumn)组成,这些列对象构成一个下标从0开始的数组:
Column[0]、Column[1]、…、Column[n-1]
当指定DBGrid的DataSource属性,并打开数据集(如:ADOTable)时,DBGrid就会自动生成这些列对象。见图图 3‑13
图 3‑12 DBGrid的动态列对象
当选中某个列对象,Object Inspector窗口中就会显示这个列对象的属性:
用户可以设置这些列对象的各个属性,如:要将某一列的文字颜色设置为红色,只要单击“Font…”,打开字体设置对话框,将文字颜色指定为红色即可。
这些列对象是动态生成的,列对象的个数就是数据集中字段的个数,无法增加也无法减少,而且DBGrid。如果想要增加或减少列对象,就要使用永久列对象。
2 、永久的列对象
假如要在上述DBGrid中删除一列:学号,该如何实现呢?
第一步:在窗体上选择DBGrid构件,然后在对象观察器中单击Columns属性边上的省略号按钮将打开如图 3‑14所示的编辑器(也可以右击DBGrid构件,在打开的快捷菜单中,选择第一项“Columns Editor …”)。
刚开始的时候,这个编辑器是空白的,因为此时还没有永久的列对象。
第二步:在“列编辑器” 窗口中单击右键,打开快捷菜单,选择其中的“Add All Fields”命令,则Delphi就会基于数据集中的每一个字段分别创建一个永久的列对象。
图 3‑15 向列编辑器窗口中添加字段
图 3‑16 已添加到列编辑器窗口中的字段
要创建一个独立的永久列对象,可以单击工具栏上的(Add New)按钮。选择这个刚创建的列对象,然后在对象观察器中设置FieldName属性指定一个字段,设置Caption属性指定列的标题。
要删除一个列对象,可以单击工具栏上的(Delete Selected)按钮。要调整列在栅格中显示的顺序,可以用鼠标把列对象前移或后移。
对于永久的列对象来说,它的属性的默认值仍然取自于字段,除非您修改了永久列对象的属性。例如,默认的情况下,列的标题就是字段的DisplayLabel属性。如果修改字段的DisplayLabel属性,列的标题将随之改变。但是,一旦您修改了列对象的Caption属性,列的标题不再与字段的DisplayLabel属性存在联动关系,它们彼此是独立的。
第三步:在“列编辑器”窗口中,选择“学号”,按<Delete>键,即可删除“学号”列。
3 、设置显示格式
无论是动态生成的列对象、还是使用列编辑器创建的永久列对象,都可以在设计时或运行时,修改列对象的属性,特别是设置列的显示格式。
要在设计时修改列对象的属性,只要在“Object TreeView”窗口中选择某列,然后在“Object Inspector”窗口中设置相应的属性。
如果要在运行时动态地修改列对象的属性,则可以通过执行如下赋值语句来实现:
DBGrid1.Columns[i].<属性名>:=<属性值>
其中,i从0到n-1(n为列的总数)
例如:要将第一列的字体改变为红色,可执行下面程序:
DBGrid1.Columns[1].Font.color:=clRed;
4 、DBGrid中显示计算字段值
利用字段编辑器,可以创建计算字段。计算字段并不是表中的真实字段,计算字段的值一般是由若干个字段经过某些运算得到的。DBGrid中同样可以显示计算字段的值,但用户无法进行修改。
例3‑5用DBGrid显示Students数据库中的“成绩单”,并显示出每个学生的总成绩。
图 3‑17 利用计算字段显示学生总成绩
步骤:
①、首先利用字段编辑器为表中全部字段创建永久性字段对象,然后再增加一个新的计算字段。
图 3‑18 在字段编辑器窗口中添加新字段
②、在“New Field”对话框中,输入计算字段名称:Total,字段类型为:Integer,然后单击“OK”。
图 3‑19 指定新字段名称、数据类型、字段类型
③、打开DBGrid的列编辑器,添加全部字段,我们就会看到,除了“学号”、“姓名”、“语文”、“数学”、“英语”六个真实字段外,计算字段Total也加入了进来。
图 3‑20 计算字段Total显示在DBGrid的列编辑器窗口中
④、在列编辑器中选择Total,然后在“Object Inspector”窗口中将“Title”属性下的“Caption”子属性修改为:总成绩。
图 3‑21 修改DBGrid中对应于计算字段Total的列标题
⑤、最后在ADOTable1的OnCalcFields事件中添加事件处理程序:
procedure TForm1.ADOTable1CalcFields(DataSet: TDataSet);
begin
ADOTable1.FieldByName('Total').AsInteger:=ADOTable1.FieldByName('语文').AsInteger+
ADOTable1.FieldByName('数学').AsInteger+ADOTable1.FieldByName('英语').AsInteger;
end;
OnCalcFields事件主要用于给出“计算字段”的值。AutoCalcFields属性的值决定了什么时候会发生OnCalcFields事件。
如果AutoCalcFields属性设为True,下列情况下会发生OnCalcFields事件:
l 数据集被打开时;
l 在数据控件中,输入焦点从一条记录移到另一条记录;
l 在数据控件中,输入焦点从一个字段移到另一个字段;
l 当前记录被修改或从数据库中检索了一条记录。
不过,即使AutoCalcFields属性设为False,当数据集中的任意一个非计算字段的值发生变化时都会触发OnCalcFields事件。
由于OnCalcFields事件有可能是频繁发生的,因此,处理OnCalcFields 事件的代码要尽可能地简短。在AutoCalcFields属性设为True的情况下,在处理OnCalcFields事件的句柄中不能修改数据集的数据,因为一旦当前记录被修改,又要触发OnCalcFields事件,从而导致无限循环。例如,假设你在处理OnCalcFields事件的句柄中调用了Post,就会触发OnCalcFields事件,导致再次调用Post,再次触发OnCalcFields事件……最终出现下面的“堆栈溢出”错误。
图 3‑22 “堆栈溢出”错误
5 、DBGrid中显示下拉列表
对于象“性别”、“血型”等字段,用户希望使用DBGrid来输入时也能通过打开选择列表来选择而不是用手工打字来输入。如下图:
图 3‑23 DBGrid中显示下拉列表
方法:利用DBGrid构件的“列编辑器”创建列对象,然后选择相应的列,设置列对象的“PickList”属性即可。见下图。
图 3‑24 创建下拉列表
6 、DBGrid中单元格右边显示“…”的按钮
当下拉列表中的选择项较多时,使用上述办法用户可能会觉得不方便,此时应该改用另一种办法,即:在相应单元格的右边显示一个带“…”的按钮,然后当用户点击该按钮时,打开一个对话框,在此对话框中显示选择列表,让用户挑选。
例3‑6在DBGrid的“现任职称”一列右侧显示一个“…”按钮,单击该按钮可以弹出对话框,从中挑选职称。
步骤:
第1步:右击窗体上的“DBGrid1”控件,选择“Columns Editor…”,打开列编辑器对话框。
第2步:右击列编辑器对话框,选择“Add All Fields”,创建永久列对象。(这一步不能省略!)
第3步:在“Object TreeView”中选择列对象“1-现任职称”,再在“Object Inspector”中将ButtonStyle属性改为“cbsEllipsis”
图 3‑25 修改列对象的ButtonStyle属性
然后,运行程序,可以看到:当鼠标单击“现任职称”一列时,列的右侧会显示包含三个点的按钮。
图 3‑26 显示三个点的按钮
第4步:创建如下窗体,其中包含“职称列表”:
图 3‑27 创建职称列表对话框
第5步:打开“Project Options”对话框,将窗体Form2移到“Avaliable forms”列表框中:
图 3‑28 “Project Options”对话框
第6步:在窗体Form2的Public下给Form2添加一个属性,用于保存用户选择的职称:
ZC:String;
在“确定”按钮的OnClick事件中,添加事件处理程序:
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
if ListBox1.ItemIndex>=0 then
begin
ZC:=ListBox1.Items[ListBox1.ItemIndex];
Close;
end
else
showmessage('请从职称列表中选择一个职称!');
end;
在DBGrid1的OnEditButtonClick事件中添加如下事件处理程序:
procedure TForm1.DBGrid1EditButtonClick(Sender: TObject);
单击图?中三个点的按钮时,就会触发此事件 |
begin
With TForm2.Create(self) do
begin
showmodal;
if ZC<>'' then
begin
ADOTable1.Edit;
ADOTable1.FieldByName('现任职称').AsString:=ZC;
ADOTable1.post;
end;
free;
end;
end;
上述例子演示了怎样将数据从一个窗体传递到另一个窗体,其中的关键之处是:在Form2中添加了一个属性ZC ,在Form2关闭前将数据赋给ZC,然后在Form1中读取这个ZC中的数据。 如果不添加ZC,就需要将Form2的“确定”按钮的OnClick事件处理程序改为: if ListBox1.ItemIndex>=0 then With Form1.ADOTable1 do begin Edit; FieldByName('现任职称').AsString:= ListBox1.Items[ListBox1.ItemIndex]; post; Close; end else showmessage('请从职称列表中选择一个职称!');
并把DBGrid1的OnEditButtonClick事件处理程序中虚线部分去掉。这样做虽然也可以,但Form2中引用了Form1中的控件ADOTable1,使得Form2严重依赖于Form1(所谓的耦合),所以不是一种好的做法。 |
1.2 数据验证
在数据录入时,经常需要对某些字段的值进行某种限制。如:员工表中的“目前月薪资”,不允许输入负数;性别字段只允许输入男或女;在学生成绩表中,成绩字段不允许输入0~100之外主的数据等等,这就要涉及到数据验证。
1.2.1 通过数据库自动进行数据验证
数据验证一是通过数据库中定义字段或记录验证规则来实现,如:“性别”字段可以定义如图 3‑29所示的字段验证规则:
有时,可能要求一条记录的几个字段之间必须满足某种关系,如:教师表中要求:
年龄-工龄>18
在这种情况下,就必须使用记录级验证规则: 可以定义如图 3‑30所示的记录验证规则,这样用户输入或修改完记录,当光标试图离开本条记录时,数据库引擎会自动进行验证,判断用户输入的数据是否满足上述规则要求。
字段级验证规则与记录级验证规则之间的区别: 前者是针对单个字段;后者针对一条记录,通常是要求记录中的几个字段之间满足某种关系。 前者当光标离开字段时进行规则验证;后者则是当光标离开当前记录时进行规则验证。 |
如果要更灵活的数据验证,则可以通过编写程序来实现。
1.2.2 通过编程进行数据验证
1、字段级数据验证
对于这种单一字段的数据验证,通常利用TField组件的OnValidate事件。当用户输入或修改字段的值,并企图使光标离开该字段时,就会自动触发OnValidate事件。
添加验证代码的步骤:
(1)、利用数据集组件的“字段编辑器”创建永久性字段。
(2)、在“字段编辑器”中选择需要验证的字段,双击“对象观察器”中的“OnValidate”事件,生成事件处理程序框架。
(3)、在上述事件处理程序框架中加入所需的验证代码。
例如:对于员工表中的“目前月薪资”,不允许输入负数,则可以在“目前月薪资”对应的永久性字段对象的“OnValidate”事件中,添加如下事件处理程序:
procedure TForm1.ADOTable1DSDesigner8Validate(Sender: TField);
begin
if ADOTable1DSDesigner8.AsInteger<0 then
Showmessage('薪资字段不允许输入负数!');
end;
图 3‑31 通过编程实现字段验证
当用户输入了一个负数,并使光标离开“目前月薪资”字段时,就会显示一个错误信息。但仅仅是显示一下而已,错误的值仍然被保存进了数据库。
正确的处理方式应该是:当检测到输入的数据错误时,产生一个错误消息框,然后将操作的焦点停留在触发错误的组件上。要实现这一目的,只要将
Showmessage('薪资字段不允许输入负数!');
改为:
Raise Exception.Create('薪资字段不允许输入负数!');
2、记录级数据验证
有时,一条记录的某几个字段之间可能存在着某种制约关系,如:“工龄”与“年龄”之间,至少需要满足:年龄-工龄>18
要验证是否满足上述条件,就必须等用户对这两个字段都输入之后,所以无法用单个字段的“OnValidate”事件去进行数据验证。
这种数据验证我们称为“记录级数据验证”(相对地,前面的单个字段的数据验证称为“字段级数据验证”)。
记录级数据验证可以利用BeforePost事件来完成。该事件是在用户输入完一行记录并试图保存时自动触发的。
添加记录级数据验证代码的步骤类似与前面单个字段类似。
课外练习:
1、 DBComboBox的items属性应该设置为_________。
A、字段名
B、字段的可能取值
C、“男”或“女”
D、True或False
2、 DBComboBox的items属性应该设置为_________。
A、字段名
B、字段的可能取值
C、“男”或“女”
D、True或False
3、 要将图片添加到图片字段中,可执行下列程序______________。
A、DBImage1.LoadFromFile(OpenPictureDialog1.FileName);
B、DBImage1.Picture:= OpenPictureDialog1.FileName;
C、DBImage1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
D、DBImage1.Picture:= LoadFromFile(OpenPictureDialog1.FileName);
4、 DBGrid的Columns[i]表示_________________。
A、第i个列对象
B、第i列中显示的值
C、表的第i个字段
D、表的第i条记录
5、 永久性字段对象的OnValidate事件在__________触发。
A、记录保存时
B、光标离开该记录时
C、字段值被保存时
D、光标离开该字段时
1、 DBCheckBox一般用于显示逻辑型字段的值。
2、 DBRadioGroup中每个单选按钮旁边显示的文字必须为字段的可能取值。
3、 DBImage构件用于显示图片字段在。既能显示位图(Bmp文件)也可以显示JPG格式的图片。
4、 DBGrid中显示的列数必须与数据库表中的字段数相同。
5、 要在DBGrid中显示下拉列表或显示三个点的按钮,必须创建永久性列对象。
6、 DBGrid可以显示计算字段的值。
7、 DBGrid的第一列能够以不同的格式显示。
8、 当修改完记录并试图保存时,将自动触发BeforePost事件。
9、 执行ADOTable1.FieldByName('姓名').SaveToStream(s)可以将姓名字段值存在到内存流s中。
10、 DBRadioGroup的Items属性与Values可以取不同的值。
11、 如果存在计算字段,则当数据集被打开时,会自动触发OnCalcFields事件。
12、 当数据集构件的Filtered属性设置为True时,会自动触发OnFilterRecord事件。