我正在尝试创建数据感知控件。我有一个TFieldDataLink对象,其中连接了DataSource和Field。在我尝试编辑值之前,一切似乎都没问题。
我正在为TFieldDataLink使用OnDataChange和OnUpdateData事件。如果我想在移动到新记录或发布之前调用OnUpdateData事件,我看起来需要调用TFieldDataLink.Edit。在下面的示例代码中,如果进行了更改,则尝试在控件的OnExit字段中调用.Edit。在我的实际应用程序中,控件包含几个DevExpress查找组合框,我试图在OnEditValueChanged中调用.Edit。
我的问题是对TFieldDataLink.Edit的调用导致OnDataChange事件再次触发。这会强制使用原始值重新加载我的编辑。如果我在数据集已经处于编辑模式后进行第二次更改,则不会触发OnDataChange事件。
这是一个测试单元,它包含一个表格上的所有内容。在我的实际应用程序中,这被分成一个更复杂的组件。
我应该何时调用.Edit而不更改OnUpdateData?我知道我可以在调用.Edit之前设置一个成员变量来停止重新加载或取消挂起事件。感觉就像我对TFieldDataLink对象有些不了解而且我不需要诉诸这些技巧。
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.
答案 0 :(得分:2)
TFieldDataLink.Edit
仅将DataSource设置为编辑状态(就像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;
至于何时应该调用TFieldDataLink.Modified
,那就是你更新了字段值的时候:
procedure TForm1.MyUpdateData(Sender: TObject);
begin
FMyDataLink.Field.AsString := Edit1.Text;
FMyDataLink.Modified;
end;
答案 1 :(得分:2)
这是一个老问题,但对于那些遇到同样问题的人来说, 你必须覆盖数据感知控件的KeyPress方法并调用FieldDataLink.Edit;继承之后;如果密钥对输入有效(包括del / c& p / bs / etc ..)。 此时,当前数据尚未修改。在这之后调用.Edit为时已晚。