Delphi FMX 无法在运行时更改 TCombobox TListItem 的下拉文本
Delphi FMX Unable to change the drop down text of a TCombobox TListItem at runtime
我正在使用 Delphi 11 Alexandria 并正在构建一个 FMX 项目以在 Windows、iOS 和 Android.
上发布
我正在构建一个手动语言翻译系统,为此我生成了一个映射文档,将语言文本映射到使用组件名称映射的组件。
我的客户坚持不应该使用自动翻译技术。
我的代码适用于接受 TComboBox
和 TListItem
的所有内容?
当我在启动时为 TListItem
设置文本值时,它起作用了。例如,设计时值是英文的,如果保存状态确定最后使用的语言是德语,那么这个函数成功地更改了下拉文本和 TComboBox
的 header 文本(很奇怪) .
但是,当我在启动后更改语言以更改所有文本时,它不会更改下拉文本,但会更改 header 文本值。
即我最初加载英文文本,保存状态加载英文,然后我更改为 Deutschland。
当我更改为 Deutschland 时,组合框中的 header 文本显示为“Bereich”,但下拉值显示为“Area”。对于所有下拉值都是如此,只有 header 文本发生变化而不是下拉值?
请注意:我已经添加了 if
语句 if cmp is TListBoxItem then
以便放置任何其他代码以使其工作。
procedure setLangTextVal(cmp: TComponent; text: string);
var
Ctx: TRttiContext;
Prop: TRttiProperty;
begin
Prop := Ctx.GetType(cmp.ClassType).GetProperty('Text');
if (Prop <> nil) and (Prop.Visibility in [mvPublic, mvPublished]) then
begin
if cmp is TListBoxItem then
Prop.SetValue(cmp, text)
else
Prop.SetValue(cmp, text);
Exit;
end;
Prop := Ctx.GetType(cmp.ClassType).GetProperty('Caption');
if (Prop <> nil) and (Prop.Visibility in [mvPublic, mvPublished]) then
begin
Prop.SetValue(cmp, text);
Exit;
end;
end;
这确实是 TListBoxItem
但 TComboBox
组件中的错误。它有一项优化,可防止每次显示下拉列表时都重新创建项目列表,除非添加或删除项目或通过 Items
属性 替换整个列表。似乎仅更改项目的文本不会触发此类下拉式娱乐。
解决方法是通过将源文件 FMX.ListBox.pas
复制到您的项目文件夹并注释掉 TCustomComboBox.InitPicker
过程中的 FItemsChanged
检查来禁用此优化:
// if FItemsChanged then <-- disable this check
// begin
AListPicker.Values := Items;
FItemsChanged := False;
// end;
注意这是基于 Delphi 11.0 源文件。 Delphi.
的 previous/future 版本的解决方法可能不同
我正在使用 Delphi 11 Alexandria 并正在构建一个 FMX 项目以在 Windows、iOS 和 Android.
上发布我正在构建一个手动语言翻译系统,为此我生成了一个映射文档,将语言文本映射到使用组件名称映射的组件。
我的客户坚持不应该使用自动翻译技术。
我的代码适用于接受 TComboBox
和 TListItem
的所有内容?
当我在启动时为 TListItem
设置文本值时,它起作用了。例如,设计时值是英文的,如果保存状态确定最后使用的语言是德语,那么这个函数成功地更改了下拉文本和 TComboBox
的 header 文本(很奇怪) .
但是,当我在启动后更改语言以更改所有文本时,它不会更改下拉文本,但会更改 header 文本值。
即我最初加载英文文本,保存状态加载英文,然后我更改为 Deutschland。
当我更改为 Deutschland 时,组合框中的 header 文本显示为“Bereich”,但下拉值显示为“Area”。对于所有下拉值都是如此,只有 header 文本发生变化而不是下拉值?
请注意:我已经添加了 if
语句 if cmp is TListBoxItem then
以便放置任何其他代码以使其工作。
procedure setLangTextVal(cmp: TComponent; text: string);
var
Ctx: TRttiContext;
Prop: TRttiProperty;
begin
Prop := Ctx.GetType(cmp.ClassType).GetProperty('Text');
if (Prop <> nil) and (Prop.Visibility in [mvPublic, mvPublished]) then
begin
if cmp is TListBoxItem then
Prop.SetValue(cmp, text)
else
Prop.SetValue(cmp, text);
Exit;
end;
Prop := Ctx.GetType(cmp.ClassType).GetProperty('Caption');
if (Prop <> nil) and (Prop.Visibility in [mvPublic, mvPublished]) then
begin
Prop.SetValue(cmp, text);
Exit;
end;
end;
这确实是 TListBoxItem
但 TComboBox
组件中的错误。它有一项优化,可防止每次显示下拉列表时都重新创建项目列表,除非添加或删除项目或通过 Items
属性 替换整个列表。似乎仅更改项目的文本不会触发此类下拉式娱乐。
解决方法是通过将源文件 FMX.ListBox.pas
复制到您的项目文件夹并注释掉 TCustomComboBox.InitPicker
过程中的 FItemsChanged
检查来禁用此优化:
// if FItemsChanged then <-- disable this check
// begin
AListPicker.Values := Items;
FItemsChanged := False;
// end;
注意这是基于 Delphi 11.0 源文件。 Delphi.
的 previous/future 版本的解决方法可能不同