데이터 인식 컨트롤을 만들려고합니다. 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.
FMyDataLink.UpdateRecord를 호출하지 않고 FMyDataLink.Edit을 호출하면 먼저 UpdateData 이벤트가 호출되지 않으므로 데이터 집합이 업데이트되지 않습니다. 즉시 데이터 집합을 편집 모드로 설정하고 싶지 않습니다. 다른 db 구성 요소처럼 첫 번째 변경이 수행 될 때까지 기다리고 싶습니다. 나는 그 첫 번째 변화를 잃지 않는 방법을 알아낼 수 없다. –
'OnExit' 핸들러에서'FMyDataLink.Modified'가 아직 호출되지 않았다면 문제가 발생합니다. 'OnExit'은 뭔가 바뀌 었다고 신호 할 필요가 없습니다. 책임은 예를 들어 편집의'OnChange' 핸들러. – NGLN
여전히 작동하지 않습니다. 수정 된 설정은 해당 필드에 대해 UpdateData가 호출되도록합니다. 그리고 그것은 편집이 호출 된 경우에만 발생합니다. 즉, 첫 번째 변경 후에 편집을 호출하면 다시로드되는 문제가 바로 있습니다. TEdit의 경우 OnChange 이벤트에서 DataLink.Edit을 호출하고 필드 끝에 문자를 입력하려고하면 다시로드 할 때 편집 내용이 지워지고 커서는 본문. –