delphi - 创建数据库感知组件 - TFieldDataLink.Edit 导致字段重新加载

标签 delphi vcl delphi-xe3

我正在尝试创建一个数据感知控件。我有一个 TFieldDataLink 对象,其中连接了 DataSource 和 Field。一切似乎都很顺利,直到我尝试编辑该值。

我正在使用 TFieldDataLink 的 OnDataChange 和 OnUpdateData 事件。如果我希望在移动到新记录或发布之前调用 OnUpdateData 事件,那么看起来我需要调用 TFieldDataLink.Edit。在下面的示例代码中,如果进行了更改,我将尝试在控件的 OnExit 字段中调用 .Edit。在我的实际应用程序中,该控件由几个 DevExpress 查找组合框组成,我尝试在 OnEditValueChanged 中调用 .Edit。

我的问题是对 TFieldDataLink.Edit 的调用导致 OnDataChange 事件再次触发。这会强制使用原始值重新加载我的编辑。如果我在数据集已处于编辑模式后进行第二次更改,则不会触发 OnDataChange 事件。

这是一个测试单元 I,所有内容都在一个表格中。在我的实际应用程序中,它被分成一个更复杂的组件。

我什么时候应该调用 .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.

最佳答案

TFieldDataLink.Edit仅将数据源设置为编辑状态(就像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;

关于delphi - 创建数据库感知组件 - TFieldDataLink.Edit 导致字段重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21416521/

相关文章:

delphi - dcef3 - Google map 欢迎始终显示

pascal - lazarus/delphi(pascal)-写入txt文件,下次不覆盖

delphi - 如何将Filter ComboBox(下拉框)变大?

delphi - 如果未设置属性,则生成编译器错误

delphi - 具有空行的 TMemo 后代

delphi - 在最大化丢失分配值之前动态分配表单大小

delphi - 如何让透明图像出现在菜单项上

c++ - RAD Studio,在设计模式下锁定项目位置

delphi - 逐位读取字节 - 简化/加速建议 - Delphi

Delphi 数组初始化