gpt4 book ai didi

delphi - 需要控件和对象之间的双向 LiveBindings

转载 作者:行者123 更新时间:2023-12-03 14:34:48 25 4
gpt4 key购买 nike

在 Delphi XE2 LiveBindings 中,我需要将任何类型的 VCL 控件绑定(bind)到任意(非组件)对象上的任何类型的属性。我可以单向地做到这一点。但我需要双向进行。

假设我想将 TPerson.PersonName: 字符串绑定(bind)到 TEdit.Text。

我现在所拥有的很简单。

  • 创建一个新的 VCL 应用程序,添加 TBindScope、TBindingsList、TEdit。
  • 创建一个名为 person1 的 TPerson 实例。
  • 使用 BindingList 添加 TBindExpression 属性。
  • 使用 BindExpression
    • 将 ControlComponent 设置为 Edit1
    • 将 ControlExpression 设置为“文本”
    • 将 SourceComponent 设置为 BindScope1
    • 将 SourceExpression 设置为 PersonName
  • 添加一个按钮;我在 Click 事件中添加: BindScope1.DataObject := person1;
  • 添加一个按钮;到我添加的 Click 事件(只需要一个,但在它起作用之前我将尝试它们)。
    • TBindings.Notify(sender, '');
    • BindingsList1.Notify(sender, '');

第一个按钮在第一个方向上绑定(bind)。第二个按钮似乎永远不会将值写回 person1.PersonName 属性。

我已经尝试过通知代码、绑定(bind)方向、绑定(bind)类型、表达式、SourceMember 等。有时我会在绑定(bind)表达式配置中遇到运行时错误,其余时间绑定(bind)只是单向的。

我希望单击第二个按钮并看到 Edit1.Text 的内容写入 person1.PersonName。

如果我必须通过代码完成这一切,我会考虑它,并且欢迎这样的示例,但如果可能的话,我真的想通过设计器来完成。

请注意,我对两个控件之间的绑定(bind)不感兴趣。

另请注意,我已经下载并检查了 LiveBinding 示例项目,但没有找到任何可以执行此操作的项目。如果这是错误的,请具体指出。我还阅读了 DocWiki。除了使用DB LiveBinding 控件之外,它不涵盖双向绑定(bind)。我没有使用DB LiveBinding 控件,也没有使用数据集。因此,除非您能向我解释为什么我应该使用它们,否则我不需要有关这些控件的任何信息。

最佳答案

我现在已经可以正常工作了。我在设计器中完成了这一切,但已将其转换为主要代码,以便在 SO 上更好地共享。

创建一个 VCL 表单项目。在表单上,​​将其中的每一项拖放到表单上:

TBindScopeTB绑定(bind)列表T按钮T按钮T编辑

将其中一个按钮重命名为 btnLoad,另一个按钮重命名为 btnSave。

将此代码粘贴到您的表单单元上(假设它名为 Form1)。为按钮分配单击处理程序并运行它。单击 btnLoad 用 TPerson 对象数据填充编辑框,将编辑框中的文本编辑为新值,然后单击 btnSave 将其写回 TPerson 对象。

unit Form1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Rtti,

// LiveBinding units
System.Bindings.Helper, // Contains TBindings class
Data.Bind.EngExt,
Vcl.Bind.DBEngExt,
Data.Bind.Components,
System.Bindings.Outputs;

type
TPerson = class(TObject)
protected
fName: string;
fAge: integer;
procedure SetName(const Value: string);
public
property Name: string read fName write SetName;
property Age: integer read fAge write fAge;
end;

type
TForm1 = class(TForm)
btnLoad: TButton;
btnSave: TButton;
BindScope1: TBindScope;
BindingsList1: TBindingsList;
Edit1: TEdit;
procedure btnLoadClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
private
fInitialized: boolean;
fPerson: TPerson;
procedure Initialize;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AfterConstruction;
begin
inherited;
Initialize;
end;

procedure TForm1.BeforeDestruction;
begin
fPerson.Free;
inherited;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
begin
fPerson.Name := 'Doogie Howser';
fPerson.Age := 15;
BindScope1.DataObject := fPerson;
end;

procedure TForm1.btnSaveClick(Sender: TObject);
begin
TBindings.Notify(Edit1, '');

// Could also do this:
//BindingsList1.Notify(Edit1, '');
end;

procedure TForm1.Initialize;
var
expression: TBindExpression;
begin
// Create a binding expression.
expression := TBindExpression.Create(self);
expression.ControlComponent := Edit1;
expression.ControlExpression := 'Text'; // The Text property of Edit1 ...
expression.SourceComponent := BindScope1;
expression.SourceExpression := 'Name'; // ... is bound to the Name property of fPerson
expression.Direction := TExpressionDirection.dirBidirectional;

// Add the expression to the bindings list.
expression.BindingsList := BindingsList1;

// Create a Person object.
fPerson := TPerson.Create;
end;

{ TPerson }

procedure TPerson.SetName(const Value: string);
begin
fName := Value;
ShowMessage('Name changed to "'+ Value +'"');
end;

end.

关于delphi - 需要控件和对象之间的双向 LiveBindings,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7478785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com