1

(非コンポーネント) オブジェクトのプロパティを更新するために livebindings を使用しようとしています。コンポーネントをオブジェクト フィールドにバインドするために使用している TPrototypeBindSource があり、実行時に TObjectBindSourceAdapter を使用しています。編集コンポーネントの onchange イベントを呼び出すと動作させることができますMyPrototypeBindSource.Refreshが、フォームのすべてのコンポーネントに対して onchange イベントを設定せずに、これを自動的に行う方法はありますか?

4

1 に答える 1

4

コントロールデータのデータオブジェクトへの自動投稿を処理するTPrototypeBindSource.AutoPost思われるものがありますが、そうではありません...ソースをよく見ると、このプロパティは内部データジェネレーターに影響を与えるだけです。

どうやら、アダプターを作成するときにこのプロパティを手動で設定する必要があります (そして、この時点で同様に設定AutoEditします)。

procedure TForm1.PrototypeBindSource1CreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
  FPerson := TPerson.Create;
  ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
  ABindSourceAdapter.AutoEdit := True;
  ABindSourceAdapter.AutoPost := True;
end;

これは、あなたが離れるたびに仕事をしますTEditTCheckBox 、データはすぐに投稿されます。

これを変更するには、publishedメソッドを使用するだけです

procedure TForm1.ControlChanged( Sender: TObject );
begin
  if Sender is TComponent
  then
    TLinkObservers.ControlChanged( Sender as TComponent );
end;

これを必要な各コントロール (例: ) に割り当ててTEdit.OnChange、データをすぐにデータ オブジェクトに取得します。

ここで全体を一気に

type
  TPerson = class
  private
    FFirstname: string;
    FLastname: string;
    FActive: Boolean;
  public
    function ToString: string; override;

    property Active: Boolean read FActive write FActive;
    property Firstname: string read FFirstname write FFirstname;
    property Lastname: string read FLastname write FLastname;
  end;

  TForm1 = class( TForm )
    PersonSource: TPrototypeBindSource; { OnCreateAdapter -> PersonSourceCreateAdapter }
    Edit1: TEdit; { OnChange -> ControlChanged }
    Edit2: TEdit; { OnChange -> ControlChanged }
    BindingsList1: TBindingsList;
    LinkControlToField1: TLinkControlToField;
    LinkControlToField2: TLinkControlToField;
    Label1: TLabel;
    ApplicationEvents1: TApplicationEvents; { OnIdle -> ApplicationEvents1Idle }
    CheckBox1: TCheckBox;
    LinkControlToField3: TLinkControlToField;
    procedure PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
    procedure ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
  private
    FPerson: TPerson;
  published
    procedure ControlChanged( Sender: TObject );
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
begin
  // just for checking then object data
  Label1.Caption := FPerson.ToString;
end;

procedure TForm1.ControlChanged( Sender: TObject );
begin
  if Sender is TComponent
  then
    TLinkObservers.ControlChanged( Sender as TComponent );
end;

procedure TForm1.PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
  FPerson := TPerson.Create;
  ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
  ABindSourceAdapter.AutoEdit := True;
  ABindSourceAdapter.AutoPost := True;
end;

{ TPerson }

function TPerson.ToString: string;
begin
  Result := FLastname + ', ' + FFirstname + ' ' + BoolToStr( FActive );
end;

LiveBinding:

アクティブ: ftBoolean -> CheckBox1/CheckedState(Self)
Firstname : ftString -> Edit1/Text
姓 : ftString -> Edit2/Text

ControlChangedメソッドをすべてのコントロールに割り当てたくない場合はTPrototypeBindSource、 を呼び出して に強制的にデータを送信させることができますTPrototypeBindSource.Post。ただし、最初に編集モードかどうかを確認する必要があります。

if PersonSource.Editing
then
  PersonSource.Post;

データを投稿する必要があるときはいつでもこれを呼び出します...いつでも 内で呼び出す場合TApplicationEvents.OnIdle

于 2015-01-30T23:22:11.167 に答える