在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一直对delphi数据敏感控件很好奇,感觉很神奇。只要简单设置一下,就显示和编辑数据,不用写一行代码。 如果不用数据敏感控件,编辑一个表字段数据并保存,我相信应用如下代码。
Table1.edit, Table1.fieldByName (‘***’) .AsString:= ‘***’; //Table1.Next;//在内部如果是edit状态,则调用Post. Table1.Post;
我也相信数据敏感控件从Table端看也应该逃不出以上方法和步骤。
1、 首先,调用edit,使数据集处于编辑状态 2、 第二,给一个字段赋值 3、 第三,调用Post保存到数据库中;
事实上vcl中也是如此处理。
为了说明举一个简单的例子,在一个Edit框中显示并能编辑数据。
在TForm1OnCreate中,Edit1设置字段1的内容。
procedure TForm1OnCreate(Sender: TObject); Begin Table1.Open; Table1.First; Edit1.Text := Table1.FieldByName(‘字段1’).AsString; End;
那么在Edit1框中编辑数据的时候,调用edit过程。
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if (Table1. State = dsBrowse) then Table1.Edit;//数据集在浏览状态时,调用Edit进入编辑状态 end;
接下来应给字段赋值,在哪里呢,还好Edit1有一个事件OnExit,在Edit1失去焦点的给字段赋值。
TForm1.Edit1Exit(Sender: TObject); Begin Table1.FieldByName(‘字段1’).AsString := Edit1.Text; End;
接下就要保存了,可以在按钮OnClick中处理了。
procedure TForm1.Button1Click(Sender: TObject); begin if (Table1. State = dsEdit) then Table1.Post;// 数据集在状编辑态时保存 Table1.Close; end;
这也算数据敏感控件,也太简陋了,不过说回来,这很能说明问题。
数据敏感控件分二部分,第一部分是控件的变化要反应到数据集,第二部分是数据集的变化要反应到控件中去,要相互作用。
现要让我们看看VCL源码中TDBEdit中处理。 第一部分控件到数据集。
procedure TDBEdit.KeyDown(var Key: Word; Shift: TShiftState); begin inherited KeyDown(Key, Shift); if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then FDataLink.Edit;//注意这里 end;
procedure TDBEdit.KeyPress(var Key: Char); begin inherited KeyPress(Key); if (Key in [#32..#255]) and (FDataLink.Field <> nil) and not FDataLink.Field.IsValidChar(Key) then begin MessageBeep(0); Key := #0; end; case Key of ^H, ^V, ^X, #32..#255: FDataLink.Edit; //注意这里 #27: begin FDataLink.Reset; SelectAll; Key := #0; end; end; end; 其中TDataLink.EditàTFieldDataLink.EditàTFieldDataLink.EditàTDataLink.EditàTDataSource.EditàTDataSet.Edit
最终调用TDataSet.edit,使数据集处于编辑状态
字段赋值过程先看CMExit消息过程;
procedure TDBEdit.CMExit(var Message: TCMExit); begin try FDataLink.UpdateRecord; //注意这里 except SelectAll; SetFocus; raise; end; SetFocused(False); CheckCursor; DoExit; end;
在FDataLink.UpdateRecord中究竟做了什么,让我们看看代码。
procedure TDataLink.UpdateRecord; begin FUpdating := True; try UpdateData; //注意这里 finally FUpdating := False; end; end;
让我们再看UpdateData是个虚函数,看它的继承类TFieldDataLink处理。
procedure TFieldDataLink.UpdateData; begin if FModified then begin if (Field <> nil) and Assigned(FOnUpdateData) then FOnUpdateData(Self); FModified := False; end; end;
再往下看
constructor TDBEdit.Create(AOwner: TComponent); begin ….. FDataLink.OnUpdateData := UpdateData; //注意这里 ……. End;
procedure TDBEdit.UpdateData(Sender: TObject); begin ValidateEdit; FDataLink.Field.Text := Text; //注意这里,哈哈终于看到了 end;
从上面我们可以看出TDBEdit给一个字段赋值过程。 TDBEdit.CMExità TDataLink.UpdateRecord à TFieldDataLink.UpdateData àTDataLink.OnUpdateDataà TDBEdit.UpdateData àTDataLink.Field.Text := Text 层层调用终于给字段赋值了。
第二部分从数据集到控件,为了和数据敏感控件交互,数据集TDataSet中定义了一系列数据事件。TDataSet的打开,关闭,编辑,插入,删除,取消,数据集的滚动,最终会通知数据敏感控件,让数据敏感控件有机会改变自己。 因此TDBEdit中有一个成员变量FFieldDataLink来接收数据集TDataSet中的数据事件,而FFieldDataLink是从TDataLink继承下来的, 让我们看看最主要的一个TDataLink.DataEvent过程。
procedure TDataLink.DataEvent(Event: TDataEvent; Info: Longint); var Active, First, Last, Count: Integer; begin if Event = deUpdateState then UpdateState else if FActive then case Event of deFieldChange, deRecordChange: if not FUpdating then RecordChanged(TField(Info)); deDataSetChange, deDataSetScroll, deLayoutChange: begin …… case Event of deDataSetChange: DataSetChanged; deDataSetScroll: DataSetScrolled(Count); deLayoutChange: LayoutChanged; end; end; deUpdateRecord: UpdateRecord; deCheckBrowseMode: CheckBrowseMode; deFocusControl: FocusControl(TFieldRef(Info)); end; end;
下面是主要数据事件的说明。 deFieldChange 一个字段数值已改变。 deRecordChange 当前记录的内容已改变。 deDataSetChange 例如调用. Insert,delet,edit等时发生 deDataSetScroll |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论