2014-01-28 35 views
1

我正在尝试创建一个数据感知控件。我有一个连接了DataSource和Field的TFieldDataLink对象。在我尝试编辑该值之前,一切似乎都没有问题。创建一个数据库感知组件--TFieldDataLink.Edit导致字段重新加载

我正在使用TFieldDataLink的OnDataChange和OnUpdateData事件。它看起来像我需要调用TFieldDataLink.Edit如果我想调用OnUpdateData事件之前移动到新的记录或张贴。在下面的示例代码中试图调用。如果进行了更改,请在控件的OnExit字段中进行编辑。在我的实际应用程序中,控件由几个DevExpress查找组合框组成,我试图在OnEditValueChanged中调用.Edit。

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

这是一个测试单位,我拥有一个表格上的所有东西。在我的实际应用程序中,这被分解成更复杂的组件。

什么时候应该调用。编辑没有得到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. 

回答

2

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; 
+0

如果您在未调用FMyDataLink.Edit的情况下调用FMyDataLink.UpdateRecord,则不会调用UpdateData事件,因此数据集永远不会更新。我不想立即将数据集置于编辑模式。我想等到第一次更改与其他数据库组件一样。我无法弄清楚如何不失去第一次改变。 –

+0

如果在'OnExit'处理程序中,'FMyDataLink.Modified'尚未被调用,那么这就是你的问题。 'OnExit'不需要表示有什么改变;该责任在于例如编辑的“OnChange”处理程序。 – NGLN

+0

仍然无法使用。设置修改似乎只能确保为该字段调用UpdateData。而且只有在调用Edit时才会发生,这正好回到了我的问题,即在第一次更改后调用编辑会导致重新加载。在TEdit的情况下,如果我在OnChange事件中调用DataLink.Edit,并尝试在字段末尾键入一个字母,我的编辑在重新加载中被清除,并且光标移回到文本。 –

2

这是一个老问题,但对于那些谁遇到同样的问题, ÿ你必须重写数据感知控件的KeyPress方法并调用FieldDataLink.Edit;继承后;如果密钥对输入有效(包括del/c & p/bs/etc ..)。 此时当前数据尚未修改。呼叫。晚于此点编辑为时已晚。

相关问题