一步一步学习使用LiveBindings(11) 绑定到自定义外观的ListBox

虽然在Firemonkey中,TListView是与LiveBindings绑定最为友善的。但是ListBox在一些短平快的中小型的选项列表中也是非常不错的选择。

在本课中,将学习到:

  • 如何自定义ListBox的外观。
  • 如何使用LiveBindings绑定到具有自定义外观的ListBox。

请将你在《一步一步学习使用LiveBindings(10)》中的项目复制一份,然后开启这次列表的实际操作。

在这个练习中,将在TGrid的右侧放一个TListBox,以便进行数据的同步演示,真实的场景中,TListBox应该是类似于上一课的TCombobox,是一个可以多选的复选框。最终效果如下图:

如果您是从《一步一步学习使用LiveBindings(8)》一路学过来的话,就会明白为什么要在那一课详细的介经如了向导,因为在那之后的几课中,都反复的在使用向导先构建绑定的控件,然后再对控件进行微调。

步骤如下:

1. 现在再次右击主窗口,单击“LiveBindings Wizard”打开向导。在向导中选择第一项“Link a Control With a Field”,在第二个任务页选择“New Control”,选择TListBox,第三个任务页选择“ProtoTypeBindSource1”,也就是Employee列表,第四个任务页选择Field为“ContactName”字段。第5个任务页什么也不选,单击Finish完成。

然后,一个与Grid保持同步的,非常简陋的TListBox就出现了。稍稍调整一下布局,效果如下图所示:

2. 从工具面板拖一个TStyleBook到主窗体,确保主窗体的StyleBook指向了这个TStyleBook控件。双击这个控件,将进入到样式设计窗口。

选中根节点StyleContainer,然后从工具栏拖一个TLayout到设计窗口上,指定高度为64,宽度为300,在属性窗口设置StyleName为“customitem”。现在有了一个空白的项。

3. 从工具面板拖一个TLayout到第2步的TLayout控件内,这个时候应该严重依赖于Structure窗口,因为很容易布局出现混乱,需要重新刷新设计面板,甚至可能需要关闭样式窗口。

先将这个TLayout指定Align为MostLeft,在这个TLayout内部,再拖一个TCheckBox控件,指定其Align为Center,StyleName为avalilNow。

再拖一个TImage控件在customitem这个TLayout内,指定其Align也为MostLeft,StyleName为icon。

布局如下所示:

4. 接下来,在customitem布局内部加一个TLayout控件,指定其Align为MostRight,在里边加一个TSpeedButton,指定其stylename为“info”。

最后,加了4个Align为Top的TText控件,分别命名为“text",“hiredate”,“Salary”和“detail”。

注意:请将控件的HitTest均设置为False。
这4个TText控件的TextSettings.HorzAlign均设为Leading,表示将从水平开头位置进行显示。

由图中可以看到,这里还放了3个accessorymore、accessorycheckmark和accessorydetail,其visiable都为false。这是复制自标准的ListBoxItemStyle。可以从工具栏拖一个新的TListBox在主界面上,手动增加一个Item,指定StyleLookUp为“listboxitembottomdetail”,然后右击鼠标,选择“Edit Custom Style...”,在StyleBook1中就会新加一个ListBoxItem1Style1样式,复制里边的3个accessory即可。

做完这一切后,将刚刚添加的TListBox删除即可。

4. 回到LiveBindings Desinger视图,由于现在绑定对象越来越多,为了更快的找到需要的对象,这里选中了ListBoxContactName和PrototypeBindSource1绑定框,右击鼠标,选择 Layers > Add to New Layer菜单项,将其添加到一个新的Layer。

在右上角的Layer下拉列表框中,会增加一个新的Layer,将它重命名为友好的名称,以后只要单击Layer名就可以快速定位到绑定框。

  • 确保将Item.text关联到ContactName。
  • Item.Detail关联到Title。
  • Item.Bitmap关联到ContactBitmap。

5. 选中一条链接,可以看到选中了属性编辑器选中了LinkListControlToFieldContactName,然后切换到Events选项卡,为OnFillingListItem添加事件处理代码。

procedure TfrmMain.LinkListControlToFieldContactNameFillingListItem(
Sender: TObject; const AEditor: IBindListEditorItem);
var
Item:TListBoxItem;
begin
//得到当前的TListBoxItem
Item:= (AEditor.CurrentObject as TListBoxItem);
//指定项的高度是样式设计器的高度
Item.Height:=68;
//指定样式为自定义的样式名。
Item.StyleLookup :='customitem';
//暂时指定Accessory为aMore.
Item.ItemData.Accessory:=TListBoxItemData.TAccessory.aMore;
end;

按F9键运行程序,自定义的ListBox果然显示了不俗的效果。

虽然有一部分文本框已经显示了数据,但是Salary、HireDate和AvailNow仍然没有显示,LinkListControlToFieldContactNameFillingListItem完整的处理代码如下:

procedure TfrmMain.LinkListControlToFieldContactNameFillingListItem(
Sender: TObject; const AEditor: IBindListEditorItem);
var
Item:TListBoxItem;
emp:TEmployee;
begin
//得到当前的TListBoxItem
Item:= (AEditor.CurrentObject as TListBoxItem);
//指定项的高度是样式设计器的高度
Item.Height:=70;
//指定样式为自定义的样式名。
Item.StyleLookup :='customitem';
//暂时指定Accessory为aMore.
Item.ItemData.Accessory:=TListBoxItemData.TAccessory.aMore;
//得到当前记录对象
emp:=bsEmployee.List[bsEmployee.CurrentIndex];
if emp<>nil then
begin
Item.StylesData['availnow'] := emp.AvailNow;
Item.StylesData['hiredate'] := formatdatetime('MM/DD/YYYY',emp.HireDate);
Item.StylesData['salary'] := format('%.2m',[Currency(emp.Salary)]);
//设置按钮的单击事件
Item.StylesData['info.OnClick'] := TValue.From<TNotifyEvent>(DoInfoClick); // set OnClick value
end;
end;

这里使用Item.StylesData键值对给样式中的其他对象进行了赋值,最后

注意这个语法TValue.From(DoInfoClick),这是为info.OnClick事件关联了事件处理代码。

代码如下:

//递归查找样式对象的函数
function FindItemParent(Obj: TFmxObject; ParentClass: TClass): TFmxObject;
begin
Result := nil;
if Assigned(Obj.Parent) then
if Obj.Parent.ClassType = ParentClass then
Result := Obj.Parent
else
Result := FindItemParent(Obj.Parent, ParentClass);
end; procedure TfrmMain.DoInfoClick(Sender: TObject);
var
Item : TListBoxItem;
begin
//得到当前样式对象的顶层TListBoxItem容器对象实例
Item := TListBoxItem(FindItemParent(Sender as TFmxObject,TListBoxItem));
//显示信息
if Assigned(Item) then
ShowMessage('你单击了 ' + IntToStr(Item.Index) + ' 号项目');
end;

FindItemParent这个函数将会查找当前Info样式对象的父项,递归直到找到TListBoxItem对象,获得当前项的信息,再用ShowMessage显示信息。

最终效果如下:

当单击“详细”按钮时,可以看到果然成功的响应了事件处理代码。

Item.ItemData实际上和Item.StylesData是完成了类似的功能,Item.ItemData会访问样式中预定义的功能,比如一个StyleName为“text”的TText控件表示文本,一个StyleName为icon的TImage用来显示图像。Accessory则用来显示右侧的按钮栏。

它们也会出现在可绑定的列表,如果无法直接绑定,只能通过Item.StylesData['salary']这样的语法进行操作。

总结

TListBox虽然提供了无比强大的自定义功能,但它仍然不是万能的,它不适合显示特别复杂的项,适合于简短的,只读的或者是外观不是特别复杂的对象。

TListView是与LiveBindings绑定友好的,更加强大的列表控件,将在下一节介绍。

一步一步学习使用LiveBindings(11) 绑定到自定义外观的ListBox的更多相关文章

  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. Linux vmstat命令快速入门

    vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入 ...

  2. Windows下配置pip指定下载源具体操作步骤

    前言 pip官方源有时候较为不稳定,对于国内用户来说,一个好的镜像源能够提高生产力.再加上有的公司和行业较为严格,无法访问互联网,所以通过配置内网的源就变成了必需的技能,本文同样适用于公司内网源的搭建 ...

  3. 华为MAAS、阿里云PAI、亚马逊AWS SageMaker、微软Azure ML各大模型深度分析对比

    一.技术架构深度对比 1. 硬件基础设施 平台 自研芯片 分布式训练方案 边缘协同能力 华为MAAS 昇腾Ascend 910 + Atlas 900集群 MindSpore + HCCL(华为集合通 ...

  4. PHP安全防御需注意点的点

    本文由 ChatMoney团队出品 sql注入 漏洞描述 当应用程序将用户输入直接拼接到sql语句中时,攻击者可以插入恶意sql代码来篡改原始查询,获取或破坏数据库信息. 防御措施 预处理语句 使用预 ...

  5. 肝了一个月整理了这份Java学习路线导图

    很多人都在问应该怎么样学习java的知识点,java有哪些知识点?最近准备面试了,java知识点太多了又不知道如何开始复习?java的知识点太多太多,学完了又忘了.所以我们可以为每个知识点都整理成一份 ...

  6. 鸿蒙Next仓颉开发语言中的数据类型总结分享

    大家好,今天总结一下仓颉中的数据类型. 数字 仓颉中的数字类型复杂多样,首先分为整型和浮点型两种,也就是Int类型和Float类型,Int类型有Int.Int8.Int32.Int64几种类型,Flo ...

  7. 禁止Apache显示文件列表

    通过.htaccess文件 可以在根目录新建或修改 .htaccess 文件中添加 .代码如下: <Files *> Options -Indexes</Files> 就可以禁 ...

  8. 解决RuntimeError: Numpy is not available

    解决RuntimeError: Numpy is not available   这是因为Numpy 版本太高,将现有Numpy卸载 pip uninstall numpy 安装numpy=1.26. ...

  9. 扩展若依@Excel注解,使其对字段的控制是否导出更加便捷

    基于若依框架实现按角色控制 Excel 字段导出功能 一.背景介绍 在我们的项目开发中,采用了若依(RuoYi)的 Java Spring 框架进行系统搭建.若依框架提供了 @Excel 注解,通过在 ...

  10. 前端开发系列117-进阶篇之ast && render

    本文将讨论 AST 转换为 渲染字符串并最终调整为 render 渲染函数的具体过程,这样的讨论有益于我们加深对常见的模板引擎其工作机制以及Vue等前端框架的理解 . 在上图中简单画出了这篇文章的代码 ...