当前位置: 首页 > news >正文

Delphi 利用LiveBindings绑定JSON数据到列表控件

Delphi通过HTTP接口从远程服务器获取JSON数据,并显示在TStringGrid控件上。

一、LiveBindings技术简介

为了提供数据绑定方案,Delphi FMX 框架提供了 LiveBindings 的技术。

LiveBindings 基本上是一种基于表达式的机制,其中通常有一个源组件和一个目标组件,目的是将一个或多个涉及源成员的表达式绑定到目标的一个或多个属性。为了实现这一点,系统需要在某个地方存储涉及组件(在表单、框架或数据模块中)的绑定表达式集合(TBindingList 组件)。为了使数据对表达式引擎可用,需要使用中间组件(BindSources)在表达式引擎和实际数据存储之间充当中介。

其中BindSources组件包含TBindSourceDB、TBindSourceDBX、TPrototypeBindSource、TAdapterBindSource。

TBindSourceDB或TBindSourceDBX的DataSet属性可以连接TFDMemTable等数据库控件;

TAdapterBindSource的Adapter属性连接TDataGeneratorAdapter控件,继而绑定TList<T>数据集。

二、解决方案

以Delphi 12.1作为开发工具,用网格控件TStringGrid显示员工信息的JSON数据,JSON数据如下:

[{"name":"宋江",
"age":29,
"mobile":"13812345678",
"startDate":"2023-09-11",
"position":"developer"
},
{"name":"卢俊义",
"age":29,
"mobile":"13812345678",
"startDate":"2023-09-11",
"position":"developer"
},
{"name":"吴用",
"age":29,
"mobile":"13812345678",
"startDate":"2023-09-11",
"position":"developer"
},
{"name":"林冲",
"age":29,
"mobile":"13812345678",
"startDate":"2023-09-11",
"position":"developer"
}]

1、窗体上添加 TBindingsList、 TAdapterBindSource、TDataGeneratorAdapter、TBindNavigator、TStringGrid组件

2、双击BindingsList1,添加TBindGridLink类型的数据绑定表达式,源组件选择AdapterBindSource1,目标组件选择StringGrid1

3、将AdapterBindSource1的Adapter设置为 DataGeneratorAdapter1

4、将BindNavigator1的DataSource设置为AdapterBindSource1

5、新建TEmployee类

TEmployee = class(TObject)privateFName: String;FAge: string;FMobile: string;FStartDate: string;FPosition: String;publicconstructor Create(const AName: String; const AAge: string; const AMobile: string;const AStartDate: string; const APosition: String); overload;property Name: String read FName write FName;property Age: string read FAge write FAge;property Mobile: String read FMobile write FMobile;property StartDate: string read FStartDate write FStartDate;property Position: String read FPosition write FPosition;end;{ TEmployee }constructor TEmployee.Create(const AName: String; const AAge: string;const AMobile: string; const AStartDate: string; const APosition: String);
begininherited Create;FName := AName;FAge := AAge;FMobile := AMobile;FStartDate := AStartDate;FPosition := APosition;
end;

6、解析JSON数据,转为TList<TEmployee>

procedure TForm1.LoadEmployListDataFromJson(AJsonStr: string);
vari: Integer;ja: TJsonArray;jo: TJSONObject;lEmployee: TEmployee;
beginja := TJSONObject.ParseJSONValue(AJsonStr) as TJSONArray;try// 注意:这里 EmployeeList 不用释放,因为它会添加到TListBindSourceAdapter,并释放EmployeeList := TList<TEmployee>.Create;for i := 0 to ja.Count-1 dobeginjo := ja.Items[i] as TJSONObject;lEmployee := TEmployee.Create(jo.GetValue('name').ToString, jo.GetValue('age').ToString,jo.GetValue('mobile').ToString, jo.GetValue('startDate').ToString, jo.GetValue('position').ToString);EmployeeList.Add(lEmployee);end;finallyja.Free;end;
end;

7、通过AdapterBindSource1的onCreateAdapter事件为TDataGeneratorAdapter添加TList<TEmployee>数据

procedure TForm1.AdapterBindSource1CreateAdapter(Sender: TObject;var ABindSourceAdapter: TBindSourceAdapter);
beginLoadEmployListDataFromJson(employeeJson);// 将 EmployeeList 数据绑定到 DataGeneratorAdapter1// 其中 Create 方法的参数 AOwnsObject 默认为 true,控件释放时,会释放 EmployeeList 对象ABindSourceAdapter := TListBindSourceAdapter<TEmployee>.Create(Self, EmployeeList);
end;

三、代码实现

完整代码如下:

unit Unit1;interfaceusesSystem.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,Data.Bind.EngExt, Fmx.Bind.DBEngExt, Data.Bind.GenData, System.Rtti,FMX.Grid.Style, Data.Bind.Controls, System.Bindings.Outputs, Fmx.Bind.Editors,Data.Bind.Components, FMX.Layouts, Fmx.Bind.Navigator,FMX.Controls.Presentation, FMX.ScrollBox, FMX.Grid, Data.Bind.ObjectScope,System.Generics.Collections, System.JSON, Fmx.Bind.Grid, Data.Bind.Grid,FMX.Objects;constemployeeJson = '[{"name":"宋江","age":29,"mobile":"13812345678","startDate":"2023-09-11","position":"developer"},'+ '{"name":"卢俊义","age":29,"mobile":"13812345678","startDate":"2023-09-11","position":"developer"},'+ '{"name":"吴用","age":29,"mobile":"13812345678","startDate":"2023-09-11","position":"developer"}, '+ '{"name":"林冲","age":29,"mobile":"13812345678","startDate":"2023-09-11","position":"developer"}]';typeTEmployee = class(TObject)privateFName: String;FAge: string;FMobile: string;FStartDate: string;FPosition: String;publicconstructor Create(const AName: String; const AAge: string; const AMobile: string;const AStartDate: string; const APosition: String); overload;property Name: String read FName write FName;property Age: string read FAge write FAge;property Mobile: String read FMobile write FMobile;property StartDate: string read FStartDate write FStartDate;property Position: String read FPosition write FPosition;end;TForm1 = class(TForm)BindingsList1: TBindingsList;AdapterBindSource1: TAdapterBindSource;DataGeneratorAdapter1: TDataGeneratorAdapter;StringGrid1: TStringGrid;BindNavigator1: TBindNavigator;LinkGridToDataSourceAdapterBindSource1: TLinkGridToDataSource;Text1: TText;procedure AdapterBindSource1CreateAdapter(Sender: TObject;var ABindSourceAdapter: TBindSourceAdapter);private{ Private declarations }EmployeeList: TList<TEmployee>;procedure LoadEmployListDataFromJson(AJsonStr: string);public{ Public declarations }end;varForm1: TForm1;implementation{$R *.fmx}{ TEmployee }constructor TEmployee.Create(const AName: String; const AAge: string;const AMobile: string; const AStartDate: string; const APosition: String);
begininherited Create;FName := AName;FAge := AAge;FMobile := AMobile;FStartDate := AStartDate;FPosition := APosition;
end;{ TForm1 }procedure TForm1.AdapterBindSource1CreateAdapter(Sender: TObject;var ABindSourceAdapter: TBindSourceAdapter);
beginLoadEmployListDataFromJson(employeeJson);// 将 EmployeeList 数据绑定到 DataGeneratorAdapter1// 其中 Create 方法的参数 AOwnsObject 默认为 true,控件释放时,会释放 EmployeeList 对象ABindSourceAdapter := TListBindSourceAdapter<TEmployee>.Create(Self, EmployeeList);
end;procedure TForm1.LoadEmployListDataFromJson(AJsonStr: string);
vari: Integer;ja: TJsonArray;jo: TJSONObject;lEmployee: TEmployee;
beginja := TJSONObject.ParseJSONValue(AJsonStr) as TJSONArray;try// 注意:这里 EmployeeList 不用释放,因为它会添加到TListBindSourceAdapter,并释放EmployeeList := TList<TEmployee>.Create;for i := 0 to ja.Count-1 dobeginjo := ja.Items[i] as TJSONObject;lEmployee := TEmployee.Create(jo.GetValue('name').ToString, jo.GetValue('age').ToString,jo.GetValue('mobile').ToString, jo.GetValue('startDate').ToString, jo.GetValue('position').ToString);EmployeeList.Add(lEmployee);end;finallyja.Free;end;
end;end.

窗体文件: 

object Form1: TForm1Left = 0Top = 0Caption = 'Form1'ClientHeight = 451ClientWidth = 582FormFactor.Width = 320FormFactor.Height = 480FormFactor.Devices = [Desktop]DesignerMasterStyle = 0object StringGrid1: TStringGridCanFocus = TrueClipChildren = TruePosition.X = 64.000000000000000000Position.Y = 144.000000000000000000Size.Width = 425.000000000000000000Size.Height = 241.000000000000000000Size.PlatformDefault = FalseTabOrder = 3RowCount = 200Viewport.Width = 421.000000000000000000Viewport.Height = 216.000000000000000000endobject BindNavigator1: TBindNavigatorPosition.X = 64.000000000000000000Position.Y = 393.000000000000000000Size.Width = 425.000000000000000000Size.Height = 41.000000000000000000Size.PlatformDefault = FalseTabOrder = 4DataSource = AdapterBindSource1xRadius = 4.000000000000000000yRadius = 4.000000000000000000endobject Text1: TTextPosition.X = 64.000000000000000000Position.Y = 40.000000000000000000Size.Width = 425.000000000000000000Size.Height = 73.000000000000000000Size.PlatformDefault = FalseText = #29992'LiveBindings'#23454#29616#32465#23450'JSON'#25968#25454#21040'Grid'TextSettings.Font.Size = 18.000000000000000000TextSettings.FontColor = claCoralendobject BindingsList1: TBindingsListMethods = <>OutputConverters = <>Left = 112Top = 232object LinkGridToDataSourceAdapterBindSource1: TLinkGridToDataSourceCategory = 'Quick Bindings'DataSource = AdapterBindSource1GridControl = StringGrid1Columns = <>endendobject AdapterBindSource1: TAdapterBindSourceAutoActivate = TrueOnCreateAdapter = AdapterBindSource1CreateAdapterAdapter = DataGeneratorAdapter1ScopeMappings = <>Left = 240Top = 232endobject DataGeneratorAdapter1: TDataGeneratorAdapterFieldDefs = <>Active = TrueAutoPost = FalseOptions = [loptAllowInsert, loptAllowDelete, loptAllowModify]Left = 392Top = 232end
end

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [CSS]一文掌握
  • 快速学会SpringBoot图形验证码生成:一步步教你打造安全验证
  • 参会记录|2024 中国多媒体大会
  • leetcode-vector
  • django如何更新数据库字段并与数据库保持同步?
  • Redis 单机和集群环境部署教程
  • React前端面试基础(一)
  • LeetCode:2110. 股票平滑下跌阶段的数目(数学 Java)
  • 【Rust光年纪】构建高效终端用户界面:Rust库全面解析
  • 【ARM】应用ArmDS移植最小FreeRTOS系统
  • Visual Studio 调试时加载符号慢
  • Web-server日志分析命令
  • Qt自定义TreeWidget,实现展开折叠按钮在右侧,且一条竖直线上对齐
  • 通过指令深入了解Linux 3
  • 基于深度学习的工业系统仿真
  • [译]CSS 居中(Center)方法大合集
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • JavaScript中的对象个人分享
  • java第三方包学习之lombok
  • js 实现textarea输入字数提示
  • SegmentFault 2015 Top Rank
  • Shell编程
  • spring-boot List转Page
  • Xmanager 远程桌面 CentOS 7
  • 半理解系列--Promise的进化史
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 前端存储 - localStorage
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 收藏好这篇,别再只说“数据劫持”了
  • ​2020 年大前端技术趋势解读
  • ​iOS实时查看App运行日志
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​如何在iOS手机上查看应用日志
  • ## 基础知识
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (02)Unity使用在线AI大模型(调用Python)
  • (5)STL算法之复制
  • (笔记)M1使用hombrew安装qemu
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .NET Framework 服务实现监控可观测性最佳实践
  • .Net mvc总结
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET分布式缓存Memcached从入门到实战
  • .NET构架之我见
  • .NET开源纪元:穿越封闭的迷雾,拥抱开放的星辰