Delphi 创建DB感知组件-TFieldDataLink.Edit会导致重新加载字段
我正在尝试创建一个数据感知控件。我有一个连接了数据源和字段的TFieldDataLink对象。在我尝试编辑值之前,一切似乎都正常 我正在为TFieldDataLink使用OnDataChange和OnUpdateData事件。如果我想在移动到新记录或过帐之前调用onUpdate数据事件,则需要调用TFieldDataLink.Edit。在下面的示例代码中,如果进行了更改,我将尝试在控件的OnExit字段中调用.Edit。在我的实际应用中,该控件由几个DevExpress查找组合框组成,我正在尝试调用。在OnEditValueChanged中编辑 我的问题是调用TFieldDataLink.Edit会导致OnDataChange事件再次激发。这将强制重新加载具有原始值的编辑。如果在数据集已经处于编辑模式后进行第二次更改,则不会触发OnDataChange事件 这是一个测试单元I,它将所有内容都放在一个表单上。在我的实际应用程序中,这被分解成一个更复杂的组件 我应该什么时候打电话。编辑而不获取要更改的更新数据?我知道我可以在调用.Edit之前设置一个成员变量来停止重新加载或取消钩住事件。感觉好像TFieldDataLink对象有一些我不了解的地方,我不需要使用这些技巧Delphi 创建DB感知组件-TFieldDataLink.Edit会导致重新加载字段,delphi,vcl,delphi-xe3,Delphi,Vcl,Delphi Xe3,我正在尝试创建一个数据感知控件。我有一个连接了数据源和字段的TFieldDataLink对象。在我尝试编辑值之前,一切似乎都正常 我正在为TFieldDataLink使用OnDataChange和OnUpdateData事件。如果我想在移动到新记录或过帐之前调用onUpdate数据事件,则需要调用TFieldDataLink.Edit。在下面的示例代码中,如果进行了更改,我将尝试在控件的OnExit字段中调用.Edit。在我的实际应用中,该控件由几个DevExpress查找组合框组成,我正在尝试
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uADStanIntf, uADStanOption, uADStanParam, uADStanError,
uADDatSManager, uADPhysIntf, uADDAptIntf, Data.DB, uADCompDataSet, uADCompClient, Vcl.StdCtrls,
Vcl.DBCtrls, Vcl.Mask, Vcl.ExtCtrls, Vcl.Grids, Vcl.DBGrids;
type
TForm1 = class(TForm)
Edit1: TEdit;
DataSource1: TDataSource;
ADMemTable1: TADMemTable;
ADMemTable1test: TStringField;
Button1: TButton;
DBEdit1: TDBEdit;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
procedure FormCreate(Sender: TObject);
procedure Edit1Exit(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FMyDataLink: TFieldDataLink;
procedure MyDataChange(Sender: TObject);
procedure MyUpdateData(Sender: TObject);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
AdMemTable1.CreateDataSet;
FMyDataLink := TFieldDataLink.Create();
FMyDataLink.DataSource := DataSource1;
FMyDataLink.FieldName := 'test';
FMyDataLink.OnDataChange := MyDataChange;
FMyDataLink.OnUpdateData := MyUpdateData;
AdMemTable1.Append;
AdMemTable1.FieldByName('test').AsString := 'my test';
AdMemTable1.Post;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FMyDataLink.OnDataChange := nil;
FMyDataLink.OnUpdateData := nil;
FMyDataLink.Free;
end;
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if Edit1.Modified = true then
begin
FMyDataLink.Edit;
FMyDataLink.Modified;
end;
end;
procedure TForm1.MyDataChange(Sender: TObject);
begin
Edit1.Text := FMyDataLink.Field.AsString;
Edit1.Modified := false;
end;
procedure TForm1.MyUpdateData(Sender: TObject);
begin
FMyDataLink.Field.AsString := Edit1.Text
end;
end.
仅将数据源设置为编辑状态,就像DataSet.Edit一样。此处不需要,但示例用法可以是:
procedure TMyCustomControl.DoPaste;
begin
FMyDataLink.Edit;
inherited DoPaste;
FMyDataLink.Modified;
end;
在控件退出时,如果记录被修改,则需要更新该记录:
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if Edit1.Modified then
try
FMyDataLink.UpdateRecord;
except
Edit1.SetFocus;
raise;
end;
end;
至于什么时候应该被调用,也就是您更新字段值的时候:
procedure TForm1.MyUpdateData(Sender: TObject);
begin
FMyDataLink.Field.AsString := Edit1.Text;
FMyDataLink.Modified;
end;
仅将数据源设置为编辑状态,就像DataSet.Edit一样。此处不需要,但示例用法可以是:
procedure TMyCustomControl.DoPaste;
begin
FMyDataLink.Edit;
inherited DoPaste;
FMyDataLink.Modified;
end;
在控件退出时,如果记录被修改,则需要更新该记录:
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if Edit1.Modified then
try
FMyDataLink.UpdateRecord;
except
Edit1.SetFocus;
raise;
end;
end;
至于什么时候应该被调用,也就是您更新字段值的时候:
procedure TForm1.MyUpdateData(Sender: TObject);
begin
FMyDataLink.Field.AsString := Edit1.Text;
FMyDataLink.Modified;
end;
这是一个老问题,但对于那些遇到同样问题的人来说, 您必须覆盖数据感知控件的按键方法,并调用FieldDataLink.Edit;继承后;如果该键对输入有效,包括del/c&p/bs/等。。。
此时,当前数据尚未修改。打电话。迟于此点编辑已经太晚了。这是一个老问题,但对于遇到同样问题的人来说, 您必须覆盖数据感知控件的按键方法,并调用FieldDataLink.Edit;继承后;如果该键对输入有效,包括del/c&p/bs/等。。。
此时,当前数据尚未修改。如果调用FMyDataLink.UpdateRecord而不调用FMyDataLink.Edit,则调用.Edit晚于此点已为时过晚。如果调用FMyDataLink.UpdateRecord而不首先调用FMyDataLink.Edit,则不会调用UpdateData事件,因此数据集永远不会更新。我不想立即将数据集置于编辑模式。我想像其他db组件一样等待第一次更改。我只是不知道如何才能不丢失第一个更改。如果在OnExit处理程序中尚未调用FMyDataLink.Modified,那么thatát就是您的问题。OnExit不需要发出改变的信号;例如,编辑的OnChange处理程序仍然不起作用。设置Modified似乎只能确保为该字段调用UpdateData。只有调用Edit时才会发生这种情况,这又回到了我的问题,即在第一次更改后调用Edit会导致重新加载。在TEdit的情况下,如果我在OnChange事件中调用DataLink.Edit并尝试在字段末尾键入一个字母,则在重新加载时,我的编辑将被清除,光标将移回文本的前面。如果您在不调用FMyDataLink的情况下调用FMyDataLink.UpdateRecord。首先编辑,则不会调用UpdateData事件,因此数据集不会被调用永远不会更新。我不想立即将数据集置于编辑模式。我想像其他db组件一样等待第一次更改。我只是不知道如何才能不丢失第一个更改。如果在OnExit处理程序中尚未调用FMyDataLink.Modified,那么thatát就是您的问题。OnExit不需要发出改变的信号;例如,编辑的OnChange处理程序仍然不起作用。设置Modified似乎只能确保为该字段调用UpdateData。只有调用Edit时才会发生这种情况,这又回到了我的问题,即在第一次更改后调用Edit会导致重新加载。在TEdit的情况下,如果我在OnChange事件中调用DataLink.Edit,并尝试在字段末尾键入字母,则在重新加载时,我的编辑将被清除,光标将移回文本的前面。