Я пытаюсь создать элемент управления с учетом данных. У меня есть объект TFieldDataLink с подключенными DataSource и Field. Казалось, все шло нормально, пока я не попытался отредактировать значение.
Я использую события OnDataChange и OnUpdateData для TFieldDataLink. Похоже, мне нужно вызвать TFieldDataLink.Edit, если я хочу, чтобы событие OnUpdateData вызывалось перед переходом к новой записи или публикации. В приведенном ниже примере кода я пытаюсь вызвать .Edit в поле OnExit элемента управления, если были внесены изменения. В моем реальном приложении элемент управления состоит из нескольких полей со списком поиска DevExpress, и я пытаюсь вызвать .Edit в OnEditValueChanged.
Моя проблема заключается в том, что вызов 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.