FireMonkey TListView 使用 LiveBindings 绑定 TObjectList

这篇博客介绍了如何在Delphi FireMonkey中使用LiveBindings将TObjectList对象中的TMyDev实例数据绑定到ListView,详细步骤包括创建对象、设置PrototypeBindSource、绑定事件及刷新数据。
摘要由CSDN通过智能技术生成

前言:

Delphi FireMonkey 的 LiveBindings 可以用来直接绑定界面元素和一个对象的属性,这样就可以把对象的值显示到界面上。常见的是将数据库 DataSet 的数据显示到界面上。

如果数据是一组对象,放到一个 TObjectList 里面,该如何做?

以下操作在 Delphi 10.4 社区版上测试通过。

正文开始:

1. 有一个对象:

TMyDev = class
  private
    FDevID: string;
    FDevName: string;
    FIsOnline: Integer;
    FIsSelected: Integer;
  public
    property DevID: string read FDevID write FDevID;
    property DevName: string read FDevName write FDevName;
    property IsOnline: Integer read FIsOnline write FIsOnline;
    property IsSelected: Integer read FIsSelected write FIsSelected;
  end;

2. 有一个存储对象的列表:

FDevList: TObjectList<TMyDev>;

3. 拖一个 PrototypeBindSource1 到 Form1 上面。双击它,弹出字段编辑器窗口。
 3.1. 字段编辑器窗口左上角有个 add new 的图标,或者右键点击字段编辑器窗口出下拉菜单选择 add,添加一个字段。
 3.2. 字段编辑器窗口里面,选择添加的字段,给它的 Name 属性设置名字,给 FieldType 属性设置这个字段的数据类型。这里要注意,字段名字要和该字段对应的对象的属性名字完全一样。
 3. 拖一个 ListView 到 Form1 上面。右键点击下拉菜单,选择 Bind Visually 菜单,IDE 的底部出现可视化绑定的界面,在这个界面里面拉线实现绑定。
 3.1. 把 ListView1 的 Synch 拉线连接 PrototypeBindSource1 的星号(*)上面。
 3.2. 把 ListView1 的 ItemText 拉线连接 PrototypeBindSource1 的 DevID 字段;

4. 选择界面上的 PrototypeBindSource1,在 IDE 的属性窗口的事件页,看到 PrototypeBindSource1 只有一个事件,双击这个事件产生代码框架,代码如下:

procedure TForm1.PrototypeBindSource1CreateAdapter(Sender: TObject;
  var ABindSourceAdapter: TBindSourceAdapter);
begin
  //PrototypeBindSource1 的事件,在这里指定它的 ABindSourceAdapter 是一个 TListBindSourceAdapter
  // 这个 TListBindSourceAdapter 对应一个 TObjectList
  ABindSourceAdapter := TListBindSourceAdapter<TMyDev>.Create(Self, FDevList, True);
end;

5. 上述 4 这个事件早于 FormCreate 事件,而这里又用到 FDevList 对象。因此,需要在 FormCreate 之前就要创建 FDevList 对象。因此,这里可以有两个办法:
5.1. constructor Create(AOwner: TComponent); override; 覆盖掉 Form 的 Create 方法,在这个方法里面创建 FDevList。

constructor TForm1.Create(AOwner: TComponent);
begin
  FDevList := TObjectList<TMyDev>.Create;
  inherited;
end;

5.2. 直接在前述事件里面创建:

procedure TForm1.PrototypeBindSource1CreateAdapter(Sender: TObject;
  var ABindSourceAdapter: TBindSourceAdapter);
begin
  FDevList := TObjectList<TMyDev>.Create;
  ABindSourceAdapter := TListBindSourceAdapter<TMyDev>.Create(Self, FDevList, True);
end;

6. 运行期增加的对象的数据,显示到 ListView1 里面:

procedure TForm1.BtnAddClick(Sender: TObject);
var
  ADev: TMyDev;
begin
  ADev := TMyDev.Create;
  ADev.DevID := 'ID-' + Self.FCount.ToString;
  ADev.DevName := 'DevName-' + Self.FCount.ToString;
  ADev.IsOnline := 0;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  //必须调用 Refresh 否则 ListView1 里面不会显示新增加的对象。
  PrototypeBindSource1.Refresh;

  Inc(Self.FCount);
end;

以下是完整的代码:

unit Unit1;
{
  测试 LiveBindings 一个 TObjectList,显示多个对象内容到 ListView 或者 ListBox
}
interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Data.Bind.Components, Data.Bind.ObjectScope, FMX.TabControl, System.Generics.Collections,
  FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
  Fmx.Bind.DBEngExt, FMX.Controls.Presentation, FMX.StdCtrls, FMX.ListView;

type
  TMyDev = class
  private
    FDevID: string;
    FDevName: string;
    FIsOnline: Integer;
    FIsSelected: Integer;
  public
    property DevID: string read FDevID write FDevID;
    property DevName: string read FDevName write FDevName;
    property IsOnline: Integer read FIsOnline write FIsOnline;
    property IsSelected: Integer read FIsSelected write FIsSelected;
  end;

  TForm1 = class(TForm)
    PrototypeBindSource1: TPrototypeBindSource;
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    TabItem2: TTabItem;
    ListView1: TListView;
    Panel1: TPanel;
    BindingsList1: TBindingsList;
    LinkListControlToField1: TLinkListControlToField;
    BtnActive: TButton;
    Label1: TLabel;
    BtnAdd: TButton;
    procedure PrototypeBindSource1CreateAdapter(Sender: TObject;
      var ABindSourceAdapter: TBindSourceAdapter);
    procedure FormCreate(Sender: TObject);
    procedure BtnAddClick(Sender: TObject);
    procedure BtnActiveClick(Sender: TObject);
  private
    { Private declarations }
    FCount: Integer;

    FDevList: TObjectList<TMyDev>;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.BtnActiveClick(Sender: TObject);
begin
  PrototypeBindSource1.Active := True;
end;

procedure TForm1.BtnAddClick(Sender: TObject);
var
  ADev: TMyDev;
begin
  ADev := TMyDev.Create;
  ADev.DevID := 'ID-' + Self.FCount.ToString;
  ADev.DevName := 'DevName-' + Self.FCount.ToString;
  ADev.IsOnline := 0;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  //必须调用 Refresh 否则 ListView1 里面不会显示新增加的对象。
  PrototypeBindSource1.Refresh;

  Inc(Self.FCount);
end;

constructor TForm1.Create(AOwner: TComponent);
var
  ADev: TMyDev;
begin
  {
  FDevList := TObjectList<TMyDev>.Create;

  ADev := TMyDev.Create;
  ADev.DevID := 'ID-1';
  ADev.DevName := 'DevName-1';
  ADev.IsOnline := 0;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  ADev := TMyDev.Create;
  ADev.DevID := 'ID-2';
  ADev.DevName := 'DevName-2';
  ADev.IsOnline := 1;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  ADev := TMyDev.Create;
  ADev.DevID := 'ID-3';
  ADev.DevName := 'DevName-3';
  ADev.IsOnline := 0;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  ADev := TMyDev.Create;
  ADev.DevID := 'ID-4';
  ADev.DevName := 'DevName-4';
  ADev.IsOnline := 0;
  ADev.IsSelected := 0;
  FDevList.Add(ADev);

  }

  inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1.Text := 'FormCreate';
  FCount := 0;
end;

procedure TForm1.PrototypeBindSource1CreateAdapter(Sender: TObject;
  var ABindSourceAdapter: TBindSourceAdapter);
begin
  //PrototypeBindSource1 的事件,在这里指定它的 ABindSourceAdapter 是一个 TListBindSourceAdapter
  // 这个 TListBindSourceAdapter 对应一个 TObjectList
  FDevList := TObjectList<TMyDev>.Create;
  ABindSourceAdapter := TListBindSourceAdapter<TMyDev>.Create(Self, FDevList, True);
end;

end.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值