2014-01-28 31 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 ..)。 此時當前數據尚未修改。呼叫。晚於此點編輯爲時已晚。

相關問題