2014-01-28 4 views
1

데이터 인식 컨트롤을 만들려고합니다. DataSource 및 Field가 연결된 TFieldDataLink 개체가 있습니다. 값을 편집하려고 할 때까지 모든 것이 잘 될 것 같았습니다.DB 인식 구성 요소 만들기 - TFieldDataLink.Edit으로 인해 필드가 다시로드됩니다.

TFieldDataLink에 대해 OnDataChange 및 OnUpdateData 이벤트를 사용하고 있습니다. 새 레코드로 이동하거나 게시하기 전에 OnUpdateData 이벤트를 호출하려면 TFieldDataLink.Edit를 호출해야합니다. 아래 예제 코드에서 변경 내용이있는 경우 컨트롤의 OnExit 필드에서 .Edit를 호출하려고합니다. 내 실제 애플 리케이션에서 컨트롤은 여러 DevExpress 조회 콤보 상자로 구성되어 있으며 OnEditValueChanged에서 .Edit를 호출하려고합니다.

내 문제는 TFieldDataLink.Edit에 대한 호출로 인해 OnDataChange 이벤트가 다시 발생합니다. 이렇게하면 원래 값으로 편집 한 내용을 강제로 다시로드 할 수 있습니다. 데이터 집합이 이미 편집 모드에있는 상태에서 두 번째 변경을 수행하면 OnDataChange 이벤트가 발생하지 않습니다.

다음은 하나의 형식으로 모든 것을 가진 테스트 유닛입니다. 내 실제 애플 리케이션에서 이것은 더 복잡한 구성 요소로 나뉘어져 있습니다.

OnUpdateData를 변경하지 않고 .Edit을 호출해야하는시기는 언제입니까? .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 TForm1.Edit1Exit(Sender: TObject); 
begin 
    if Edit1.Modified then 
    try 
     FMyDataLink.UpdateRecord; 
    except 
     Edit1.SetFocus; 
     raise; 
    end; 
end; 

: 대신 컨트롤의 출구에서 원하는 무엇

procedure TMyCustomControl.DoPaste; 
begin 
    FMyDataLink.Edit; 
    inherited DoPaste; 
    FMyDataLink.Modified; 
end; 

는이 변경되는 경우, 기록을 업데이트하는 것입니다 TFieldDataLink.Modified은 당신이 필드 값을 업데이트 한 경우이다,라고해야합니다

procedure TForm1.MyUpdateData(Sender: TObject); 
begin 
    FMyDataLink.Field.AsString := Edit1.Text; 
    FMyDataLink.Modified; 
end; 
+0

FMyDataLink.UpdateRecord를 호출하지 않고 FMyDataLink.Edit을 호출하면 먼저 UpdateData 이벤트가 호출되지 않으므로 데이터 집합이 업데이트되지 않습니다. 즉시 데이터 집합을 편집 모드로 설정하고 싶지 않습니다. 다른 db 구성 요소처럼 첫 번째 변경이 수행 될 때까지 기다리고 싶습니다. 나는 그 첫 번째 변화를 잃지 않는 방법을 알아낼 수 없다. –

+0

'OnExit' 핸들러에서'FMyDataLink.Modified'가 아직 호출되지 않았다면 문제가 발생합니다. 'OnExit'은 뭔가 바뀌 었다고 신호 할 필요가 없습니다. 책임은 예를 들어 편집의'OnChange' 핸들러. – NGLN

+0

여전히 작동하지 않습니다. 수정 된 설정은 해당 필드에 대해 UpdateData가 호출되도록합니다. 그리고 그것은 편집이 호출 된 경우에만 발생합니다. 즉, 첫 번째 변경 후에 편집을 호출하면 다시로드되는 문제가 바로 있습니다. TEdit의 경우 OnChange 이벤트에서 DataLink.Edit을 호출하고 필드 끝에 문자를 입력하려고하면 다시로드 할 때 편집 내용이 지워지고 커서는 본문. –

2

그것은 오래된 질문이다,하지만 같은 문제가 발생하는 사람들을 위해, Y o 데이터 인식 컨트롤의 KeyPress 메서드를 재정의하고 FieldDataLink.Edit; 후에 상속 된; 키가 입력에 유효하면 (del/c & p/bs/etc .. 포함). 현재 데이터가 아직 수정되지 않았습니다. 이 시점 이후로 .Edit를 호출하는 것은 너무 늦었습니다.