我的软件主要基于 Firemonkey TListView,它是根据 Delphi Samples 项目中的“SampleListViewMultiDetailAppearanceProject”定制的。
"C:\Users\Public\Documents\Embarcadero\Studio\14.0\Samples\Object Pascal\Mobile Samples\User Interface\ListView\"
这是它的样子,使用 PrototypeBindSource:
每条记录显示 1 个图像和 4 个文本项。
我使用 TMS Aurelius 作为数据集,它连接到 BindSource。它是使用所有标准字段类型的 TDataset 后代。
它实现了内部的 TBlobField:
TBlob = record
private
FIntData: TArray<byte>;
在 DataSet 上,这个字段被定义为“像”一个计算字段,因为它是一个基于实体的框架 (ORM),每条记录代表一个对象,但最后是相同的东西,检索到的数据是一个带有原始数据的字段。
我的意图是根据记录的某些状态设置从项目资源(项目->资源和图像)加载的不同图像。存储的图像是一个小的 PNG 图像 (48x48)。
要读取从资源中存储的 PNG 图像,我使用的是:
procedure TEntity.AssignResource(AName: String; ABlob: TBlob);
var
InStream: TResourceStream;
begin
InStream := TResourceStream.Create(HInstance, AName, RT_RCDATA);
try
ABlob.LoadFromStream(InStream);
except
InStream.Free;
end;
end;
当实时绑定系统检索到 TBlobField 时,调用的函数是这样的:
function TEntity.GetImage: TBlob;
begin
if FImage.IsNull then
AssignResource('default', FImage);
result := FImage;
end;
FImage 是一个带有一些辅助功能的 TBlob 类型,但就像我说的那样,它是一个 TArray 并且没有任何类型的处理,只是一个容器。
所以,FImage 是直接转到 FMX TListView 的 TBitmap。
没有任何反应,没有图像显示。
我尝试了以下代码:
TValueRefConverterFactory.RegisterConversion(TypeInfo(TBlob), TypeInfo(TBitMap), TConverterDescription.Create(
procedure(const I: TValue; var O: TValue)
var
Blob: TBlob;
BitMap: TBitMap;
begin
Blob := I.AsType<TBlob>;
BitMap := O.AsType<TBitMap>;
end,
'BlobToBitMap' + GetTypeName(TypeInfo(TBlob)), 'BlobToBitMap' + GetTypeName(TypeInfo(TBitMap)), 'Nahar.LiveBinding', True, '', nil
));
从与图像无关的其他类型的转换中获得此代码。但它显然是错误的,除了它编译的事实。
这段代码中的问题: - 它似乎被注册了,我放置了一个断点,并且 RegisterConversion 确实被执行了,但是在匿名过程中,里面的断点永远不会被执行。在创建任何包含 TLisviews 的框架之前,我在初始化部分注册了它。- 在匿名程序中,转换本身纯属虚构;因为我相信 Blob 存储为 png 并且输出应该是 fmx 位图。我不知道在那里写什么。
关于这个主题的文档很少,对我的理解没有帮助。
我想知道如何在这个过程中正确地制作序列:
- 我需要从 png 转换为位图吗?如何?
- 我需要注册转换适配器吗?如何?为什么不被解雇?
- 此转换适配器内的正确转换代码是什么?
或者
我看到 TDataset 上有一个 ftGraphic TField,我可以创建该类型的字段。但是有这样的问题: - 这种类型的预期 TField 返回是什么?- 我的代码在平台之间共享:VCL 和 FMX,以及 TBitMap 或 TGraphic 在两者上都不相同。这种共享是由一个没有作用域的 bpl 包进行的。这是必需的,因为我注册了其他 bpls 的冲突。我有一个共享的通用 bpl 和其他使用它的平台特定 bpl。
由于我还没有找到解决平台单元的这种 bpl 共享和不兼容的方法,我切换到第一个选项,尝试在数据库级别处理原始数据,并让转换发生在 livebinding 级别,已经在每个平台的域中
我完全不了解与图像相关的操作,特别是在转换和正确的对象创建方面,以避免内存泄漏。
重要提示:它也必须是跨平台的,因为 fmx 应用程序是在 android 上使用的。