一步一步学习使用LiveBindings(5) 使用TAdapterBindSource实现对象绑定

在本系列的第1课介绍过TBindSourceDB绑定到TFDMemTableo数据库组件,也介绍了使用TPrototypeBindSource提供样本数据源。接下来看一个新的BindSource组件TAdapterBindSource,如其名所暗示,它是一个桥接器绑定控件,主要用来将自定义的对象与数据源进行绑定。

TAdapterBindSource有一个Adapter属性,它可以接收一个继承自TBindSourceAdapter的组件。Delphi提供了TDataGeneratorAdapter组件,它可以完成类似TPrototypeBindSource组件所完成的工作:定义字段列表,关联数据生成器。

好了,有深度的话不多说了,开始练习吧,打开Delphi 12.3。

1. 单击主菜单中的 File > New > Multi-Device Application - Delphi > Blank Application ,创建一个新的多设备应用程序。

建议立即单击工具栏上的Save All按钮,将单元文件保存为uMainForm.pas,将项目保存为LiveBinding_BindToObject.dproj。

你的项目结构应该像这样:

2. 从工具面板,拖如下的控件到主窗体。

  • TAdapterBindSource —— 通过它来完成控件绑定操作。
  • TDataGeneratorAdapter —— 通过它来产生设计时的测试数据。
  • TBindNavigator —— 将为示例数据提供导航功能。
  • TGrid —— 将显示某些信息。

简单布局一下之后,界面显示效果如下图所示。

3. 创建一个新的Delphi单元,构建将要被绑定的数据对象。可以在Project Manager右击项目名称,选择 Add > New > Unit 菜单项,新建一个单元文件,将该单元另存为“EmployeeAdaptee.pas”,然后将下面的代码敲进去。

unit EmployeeAdaptee;

interface

type
TEmployee = class(TObject)
private
FFirstName: String; //员工姓
FLastName: String; //员工名
FAge: Byte; //年龄
FStartDate: TDate; //入职日期
FPosition: String; //职位
FManager: String; //所属经理
public
/// <code>
/// 构造函数
/// </code>
constructor Create(const AFirstName, ALastName: String; const AAge: Byte;
const AStartDate: TDate; const APosition, AManager: String); overload;
property FirstName: String read FFirstName write FFirstName;
property LastName: String read FLastName write FLastName;
property Age: Byte read FAge write FAge;
property StartDate: TDate read FStartDate write FStartDate;
property Position: String read FPosition write FPosition;
property Manager: String read FManager write FManager;
end; implementation { TEmployee } constructor TEmployee.Create(const AFirstName, ALastName: String; const AAge: Byte;
const AStartDate: TDate; const APosition, AManager: String);
begin
inherited Create; FFirstName := AFirstName;
FLastName := ALastName;
FAge := AAge;
FStartDate := AStartDate;
FPosition := APosition;
FManager := AManager;
end;
end.

4. 回到主窗体,按F12切换到代码视图,再按下Alt+F11快捷键,在弹出的窗口中选中EmployeeAdaptee.pas,指定将该单元添加到Interface区中。

如果现在切换到LiveBindings Designer设计器,在AdapterBindSource1项中是看不到有任何字段的,为了添加设计时的支持,接下来将AdapterBindSource1的Adapter指向DataGeneratorAdapter1。

5. 选中AdapterBindSource1,指定其Adapter属性为DataGeneratorAdapter1。

6. 右键单击DataGeneratorAdapter1,从弹出的菜单中选择“Fields Editor”菜单项,在弹出的对话框中,单击“Add”按钮,在弹出的对话框中可以看到有很多包含FieldData生成器的字段,也有很多是Generator为(none)类型的不包含生成器的字段。在名称文本框中会自动生成Field开头的字段,依次添加如下图所示的字段:

7. 现在,如果进入到LiveBindings Designer设计器,可以看到AdapterBindSource1实体中包含了多个字段,这个时候可以通过拖拉的方式来设置绑定。

由于在添加字段时,指定了具体的字段数据生成器,因此在绑定后,就可以在Grid上看到测试数据。

8. 接下来需要通过一个事件,来将雇员信息添加到数据绑定中去,请选中AdapterBindSource1组件,然后在属性编辑器中,切换到Events选项卡,双击OnCreateAdapter事件,Delphi将生成骨架代码,然后将如下的代码添加进来。

首先,在Interface的Uses区中添加如下的引用,在第4步已经添加了EmployeeAdaptee,接下来需要添加泛型集合类的引用。

接下来需要在private区添加一个集合变量。

type
TFrmMain = class(TForm)
AdapterBindSource1: TAdapterBindSource;
DataGeneratorAdapter1: TDataGeneratorAdapter;
BindNavigator1: TBindNavigator;
Grid1: TGrid;
BindingsList1: TBindingsList;
LinkGridToDataSourceAdapterBindSource1: TLinkGridToDataSource;
private
{ Private declarations }
//定义一个集合类
FMyEmployee: TObjectList<TEmployee>;
public
{ Public declarations }
end;

FMyEmployee将会作为对象数据绑定到TGrid上。

接下来添加OnCreateAdapter事件处理代码:

procedure TFrmMain.AdapterBindSource1CreateAdapter(Sender: TObject;
var ABindSourceAdapter: TBindSourceAdapter);
begin
//创建员工集合
FMyEmployee := TObjectList<TEmployee>.Create(True);
//创建单个员工并添加到集合
FMyEmployee.Add(TEmployee.Create('Gomez', 'Addams', 40,Now-365*10,'Software Engineer','Alex'));
FMyEmployee.Add(TEmployee.Create('Morticia', 'Addams', 38,Now-365*10,'Software Engineer','Alex'));
FMyEmployee.Add(TEmployee.Create('Pugsley', 'Addams', 8,Now-365*10,'Software Engineer','Alex'));
FMyEmployee.Add(TEmployee.Create('Wednesday', 'Addams', 12,Now-365*10,'Software Engineer','Alex'));
// 可以使用TObjectBindSourceAdapter指定单个对象,
// 示例使用TListBindSourceAdapter指定集合对象。
ABindSourceAdapter := TListBindSourceAdapter<TEmployee>.Create(Self, FMyEmployee, True);
end;

在OnCreateAdapter事件中,ABindSourceAdapter将被用来生成AdapterBindSource1所使用的真实的数据,示例使用TListBindSourceAdapter类创建了一个TObjectList泛型集合类的员工列表,当然也可以使用TObjectBindSourceAdapter指定单一员工对象。

7. 现在就完成了所有的工作,万事皆备,只欠一Run了,按下F9,或者是主菜单的“Run > Run”菜单项,可以看到,果然现在Grid显示了在OnCreateAdapter事件中创建的员工列表。

好了,非常漂亮。

虽然本系列已经写到第5课,但是离真实应用仍然还是有一定的距离,不要着急,只要跟着本系列一步一步的学,很快就能掌握到LiveBindings的精华。

一步一步学习使用LiveBindings(5) 使用TAdapterBindSource实现对象绑定的更多相关文章

  1. 12.Linux软件安装 (一步一步学习大数据系列之 Linux)

    1.如何上传安装包到服务器 有三种方式: 1.1使用图形化工具,如: filezilla 如何使用FileZilla上传和下载文件 1.2使用 sftp 工具: 在 windows下使用CRT 软件 ...

  2. (转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性

    转发:微软MVP 卢建晖 的文章,希望对大家有帮助.原文:http://blog.csdn.net/kinfey/article/details/44459625 编者语 : 昨晚写好的文章居然csd ...

  3. (转) 一步一步学习ASP.NET 5 (二)- 通过命令行和sublime创建项目

    转发:微软MVP 卢建晖 的文章,希望对大家有帮助. 注:昨天转发之后很多朋友指出了vNext的命名问题,原文作者已经做出了修改,后面的标题都适用 asp.net 5这个名称. 编者语 : 昨天发了第 ...

  4. 一步一步学习SignalR进行实时通信_1_简单介绍

    一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 ...

  5. 一步一步学习SignalR进行实时通信_8_案例2

    原文:一步一步学习SignalR进行实时通信_8_案例2 一步一步学习SignalR进行实时通信\_8_案例2 SignalR 一步一步学习SignalR进行实时通信_8_案例2 前言 配置Hub 建 ...

  6. 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序

    原文:一步一步学习SignalR进行实时通信_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信\_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信_9_托管在非We ...

  7. 一步一步学习SignalR进行实时通信_7_非代理

    原文:一步一步学习SignalR进行实时通信_7_非代理 一步一步学习SignalR进行实时通信\_7_非代理 SignalR 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 ...

  8. 一步一步学习SignalR进行实时通信_5_Hub

    原文:一步一步学习SignalR进行实时通信_5_Hub 一步一步学习SignalR进行实时通信\_5_Hub SignalR 一步一步学习SignalR进行实时通信_5_Hub 前言 Hub命名规则 ...

  9. 一步一步学习SignalR进行实时通信_6_案例

    原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...

  10. 一步一步学习SignalR进行实时通信_4_Hub

    原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...

随机推荐

  1. 【晴神宝典刷题路】codeup+pat 题解索引(更新ing

    记录一下每天的成果,看多久能刷完伐 c2 c/c++快速入门 <算法笔记>2.3小节--C/C++快速入门->选择结构 习题4-10-1 奖金计算 <算法笔记>2.4小节 ...

  2. JDK网站最终的拼图

    "JDK源码剖析网"目前只上线了一小部分的内容(而且还未更新完成),Javac编译器,HotSpot基础.垃圾收集器以及HotSpot运行时将在今年10月份之前做为付费内容努力更新 ...

  3. 必看!手把手教你玩转Dify的3大核心工具!

    Dify 中的工具是指其平台内置或支持集成的功能插件,用于扩展 AI 应用的能力. 1.工具作用 扩展 LLM 的能力:工具可以赋予 LLM 连接外部世界的能力,例如联网搜索.科学计算.绘制图片等.例 ...

  4. odoo14使用的文件服务器【NFS】

    linux系统之间要文件共享实现方式:目前测试系统为Ubuntu20.04LTS 条件:1.保证两个系统都是linux:            2.目前实现是同一个局域网内: 服务端:172.26.1 ...

  5. 弹性公网IP的五大核心优势解析

    在云服务架构中,弹性公网IP(EIP)已成为现代企业网络部署的核心组件.与传统固定IP相比,它通过独特的技术机制解决了动态环境下的公网访问难题.以下五大核心优势决定了其不可替代的价值: 一.动态绑定的 ...

  6. Django Web应用开发实战第一章

    一.常见域名后缀 .com:商业性的机构或公司. .net:从事Internet相关的网络服务的机构或公司. .org:非营利的组织.团体. .gov:政府部门. .cn:中国国内域名. .com.c ...

  7. 你认为Vonajs提供的这些特性会比Nestjs更好用吗?

    Nestjs是一款非常强大的Node.js框架,而且入门非常容易,但是随着项目的增长,各种不便之处就会显现出来,许多代码书写起来不再像项目刚启动时直观.而Vonajs是一款全新的Node.js框架,提 ...

  8. 曾经风光无限的 Oracle DBA 已经落伍了吗?

    先讲一个残酷的事实,Oracle DBA,若仍停留在纯粹的运维方向,未来的路将会越走越窄,尤其是在国内的特殊环境下,可以说是前途渺茫,举步维艰. 既然如此,那Oracle DBA们应该如何破局呢? P ...

  9. go 进阶训练营 微服务可用性(下)笔记

    降级: 减少工作量,丢弃不重要的请求. 确定具体采用哪个指标作为流量评估和优雅降级的决定性指标: 如 CPU.延迟.队列长度.线程数量.错误等 当服务进入降级时,需要执行什么动作? 流量抛弃或者优雅降 ...

  10. Error: Activity class MainActivity does not exist.

    这是一个熟悉而又陌生的错误,当年做的第一个React-Native项目就有这个错误,一直没有解决,今天又出现了,原因是我改了项目文件夹的名称,用Android Studio重新打开之后,就又出现了这个 ...