在 Delphi 的 android 应用程序中搜索在运行时创建的标签
Search for a Label which created on runtime in android app in Delphi
在一个 android 应用程序中,在一个 ListBox 中,我正在创建 ListBoxItems,在每个 Item 中有一个 reactangle,在每个矩形中,我正在 运行 TIME 中动态地处理 5 个标签,5创建的每个列表框项目的标签。标签中唯一唯一的 属性 是为创建的每个列表框项目更改的名称。现在,我找不到找到特定标签来更改其文本的方法 属性。我可以在哪个 Listboxitem 中找到哪个矩形是我想要的标签(使用 tag_num 变量),但我无法确定要更改其文本的特定标签。
创建Listboxitems的代码
...
lbim := TListBoxItem.Create(ListBox1);
lbim.Parent := ListBox1;
lbim.TextSettings.Font.Size := 12;
lbim.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lbim.Text := LJsonValue1_2.Value;
lbim.Height := 50;
lbim.Margins.Top := 2;
rctg := TRectangle.Create(lbim);
rctg.Parent := lbim;
rctg.Align := TAlignLayout.Client;
rctg.Stroke.Kind := TBrushKind.Solid;
rctg.Stroke.Color := $FF51ABAE;
rctg.Stroke.Thickness := 1;
rctg.Tag := tag_num;
rctg.OnClick:=QuantityClick;
rctg.Margins.Left:=2;
rctg.Margins.Right:=2;
rctg.Index := -5;
lb := TLabel.Create(rctg);
lb.Parent := rctg;
lb.Align := TAlignLayout.Center;
lb.TextSettings.HorzAlign := TTextAlign.Leading;
lb.Width := 150;
lb.Name := 'value0_'+IntToStr(tag_num);
lb.TextSettings.Font.Size := 12;
lb.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lb.Margins.Right := 180;
lb.Margins.Bottom := 35;
lb.Text := LJsonValue1_1.Value;
lb1 := TLabel.Create(rctg);
lb1.Parent := rctg;
lb1.Align := TAlignLayout.Center;
lb1.TextSettings.HorzAlign := TTextAlign.Trailing;
lb1.Width := 150;
lb1.Name := 'value1_'+IntToStr(tag_num);
lb1.TextSettings.Font.Size := 12;
lb1.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lb1.Margins.Bottom := 35;
lb1.Margins.left := 180;
lb1.Text := LJsonValue4_2.Value;
...
tag_num:=tag_num+1;
等等...
可以从 1 个 ListBoxItem 创建到 15 个或更多。如何更改,例如第 10 个 lIstBoxItem 中的 lb1 标签,其文本?
我在这里 Search for a Label by its Caption 发现了类似的问题,但对我不起作用。有什么想法吗?
我的搜索代码是:
for i := 0 to ListBox1.Items.Count - 1 do
begin
item := Form1.ListBox1.ListItems[i];
if item.Components[i] is TLabel then
begin
if TLabel(item.Components[i]).Name = 'value1' then
begin
if ed_quant1.Text = '' then
begin
ed_quant1.Text := '0';
TLabel(item.Components[i]).Text := ed_quant1.Text;
end
else
begin
TLabel(item.Components[i]).Text := ed_quant1.Text;
end;
end;
if TLabel(item.Components[i]).Name = 'value2' then
begin
if ed_quant2.Text = '' then
begin
ed_quant2.Text := '0';
TLabel(item.Components[i]).Text := ed_quant1.Text;
end
else
begin
TLabel(item.Components[i]).Text := ed_quant1.Text;
end;
end;
end;
end;
我应该提到搜索是在创建列表框的另一种形式中进行的。
这实际上很简单,但你的方法似乎比应该的要复杂得多。
当您动态创建 TlistboxItem,然后创建 TLabel 并将您创建的 TLisboxItem 设置为所有者时,标签不需要唯一名称。它需要对项目是唯一的,但不是全局的。
示例:
您不能在同一个项目中动态创建 2 个名称相同的标签,但可以在 2 个不同的项目中使用相同的名称。
创建带有标签的新列表框项目的示例:
// Creating New Items
lst1.BeginUpdate;
try
for var I := 0 to 100 do
begin
// Create Listbox Item
var
aItem := TListBoxItem.Create(lst1);
aItem.Parent := lst1;
aItem.Height := 50;
// Create label in listbox item
var
aLabel := TLabel.Create(aItem);
aLabel.Parent := aItem;
aLabel.Text := 'Test';
// Has to be unique when the same item is parent but not anywhere
// else so you can use the name "lblTest" over and over for each new item
aLabel.Name := 'lblTest';
end;
finally
lst1.EndUpdate;
end;
更改列表框项目中那些动态标签的示例:
// Changing item labels
lst1.BeginUpdate;
try
for var I := 0 to lst1.Count - 1 do
begin
var
aItem := lst1.ListItems[I];
(aItem.FindComponent('lblTest') as TLabel).Text := 'Changed';
end;
finally
lst1.EndUpdate;
end;
编辑:
由于 rctg
是您标签的父级,因此您将使用以下内容:
(rctg.FindComponent('lblTest') as TLabel).Text := 'Changed';
在提出这样的问题时,最好提供一个简化版本的代码,这样更容易理解。但是,我相信以下内容应该有用。 (我只在 Windows 上试过,未在 Android 上试过,但我不认为这会有所作为。)
首先,您的搜索代码存在问题,因为您使用相同的循环变量 (i
) 来获取两个不同的控件。也就是说,当您获得第一个项目时,您正在寻找该项目中的第一个组件,而在第二个项目中,您正在寻找第二个组件,依此类推。您需要单独的循环变量。
只要您搜索的是正确的列表框,那么您从其他表单搜索应该没有什么区别。
我没有尝试使用 .Components[]
属性,因为它可以包含 non-control 组件,而您只需要 TLabel
s,它们是控件。但是,我不明白为什么这也行不通。
我下面的代码并没有完全复制您的 search-and-replace 目标,因此您当然必须对其进行调整。在我的列表中,我将标签命名为 'value0_'+n.ToString
,其中 n
只是列表项中的 n-th 标签。所以你必须相应地调整它。
procedure TForm1.ChangeLabels;
var Item: TListBoxItem;
i,j: Integer;
Ctrl: TControl;
Lbl: TLabel absolute Ctrl;
begin
for i:=0 to ListBox1.Count-1 do begin
Item:=ListBox1.ListItems[i];
for j:=0 to Item.ControlsCount-1 do begin
Ctrl:=Item.Controls[j];
if Ctrl is TLabel then begin
if Lbl.Name='value0_3' then Lbl.Text:='CHANGED IT!';
if Lbl.Name='value0_4' then Lbl.Text:='Another one!';
end;
end;
end;
end;
在一个 android 应用程序中,在一个 ListBox 中,我正在创建 ListBoxItems,在每个 Item 中有一个 reactangle,在每个矩形中,我正在 运行 TIME 中动态地处理 5 个标签,5创建的每个列表框项目的标签。标签中唯一唯一的 属性 是为创建的每个列表框项目更改的名称。现在,我找不到找到特定标签来更改其文本的方法 属性。我可以在哪个 Listboxitem 中找到哪个矩形是我想要的标签(使用 tag_num 变量),但我无法确定要更改其文本的特定标签。
创建Listboxitems的代码
...
lbim := TListBoxItem.Create(ListBox1);
lbim.Parent := ListBox1;
lbim.TextSettings.Font.Size := 12;
lbim.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lbim.Text := LJsonValue1_2.Value;
lbim.Height := 50;
lbim.Margins.Top := 2;
rctg := TRectangle.Create(lbim);
rctg.Parent := lbim;
rctg.Align := TAlignLayout.Client;
rctg.Stroke.Kind := TBrushKind.Solid;
rctg.Stroke.Color := $FF51ABAE;
rctg.Stroke.Thickness := 1;
rctg.Tag := tag_num;
rctg.OnClick:=QuantityClick;
rctg.Margins.Left:=2;
rctg.Margins.Right:=2;
rctg.Index := -5;
lb := TLabel.Create(rctg);
lb.Parent := rctg;
lb.Align := TAlignLayout.Center;
lb.TextSettings.HorzAlign := TTextAlign.Leading;
lb.Width := 150;
lb.Name := 'value0_'+IntToStr(tag_num);
lb.TextSettings.Font.Size := 12;
lb.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lb.Margins.Right := 180;
lb.Margins.Bottom := 35;
lb.Text := LJsonValue1_1.Value;
lb1 := TLabel.Create(rctg);
lb1.Parent := rctg;
lb1.Align := TAlignLayout.Center;
lb1.TextSettings.HorzAlign := TTextAlign.Trailing;
lb1.Width := 150;
lb1.Name := 'value1_'+IntToStr(tag_num);
lb1.TextSettings.Font.Size := 12;
lb1.StyledSettings:=
[TStyledSetting.Family,TStyledSetting.Style,TStyledSetting.FontColor];
lb1.Margins.Bottom := 35;
lb1.Margins.left := 180;
lb1.Text := LJsonValue4_2.Value;
...
tag_num:=tag_num+1;
等等... 可以从 1 个 ListBoxItem 创建到 15 个或更多。如何更改,例如第 10 个 lIstBoxItem 中的 lb1 标签,其文本? 我在这里 Search for a Label by its Caption 发现了类似的问题,但对我不起作用。有什么想法吗?
我的搜索代码是:
for i := 0 to ListBox1.Items.Count - 1 do
begin
item := Form1.ListBox1.ListItems[i];
if item.Components[i] is TLabel then
begin
if TLabel(item.Components[i]).Name = 'value1' then
begin
if ed_quant1.Text = '' then
begin
ed_quant1.Text := '0';
TLabel(item.Components[i]).Text := ed_quant1.Text;
end
else
begin
TLabel(item.Components[i]).Text := ed_quant1.Text;
end;
end;
if TLabel(item.Components[i]).Name = 'value2' then
begin
if ed_quant2.Text = '' then
begin
ed_quant2.Text := '0';
TLabel(item.Components[i]).Text := ed_quant1.Text;
end
else
begin
TLabel(item.Components[i]).Text := ed_quant1.Text;
end;
end;
end;
end;
我应该提到搜索是在创建列表框的另一种形式中进行的。
这实际上很简单,但你的方法似乎比应该的要复杂得多。
当您动态创建 TlistboxItem,然后创建 TLabel 并将您创建的 TLisboxItem 设置为所有者时,标签不需要唯一名称。它需要对项目是唯一的,但不是全局的。
示例: 您不能在同一个项目中动态创建 2 个名称相同的标签,但可以在 2 个不同的项目中使用相同的名称。
创建带有标签的新列表框项目的示例:
// Creating New Items
lst1.BeginUpdate;
try
for var I := 0 to 100 do
begin
// Create Listbox Item
var
aItem := TListBoxItem.Create(lst1);
aItem.Parent := lst1;
aItem.Height := 50;
// Create label in listbox item
var
aLabel := TLabel.Create(aItem);
aLabel.Parent := aItem;
aLabel.Text := 'Test';
// Has to be unique when the same item is parent but not anywhere
// else so you can use the name "lblTest" over and over for each new item
aLabel.Name := 'lblTest';
end;
finally
lst1.EndUpdate;
end;
更改列表框项目中那些动态标签的示例:
// Changing item labels
lst1.BeginUpdate;
try
for var I := 0 to lst1.Count - 1 do
begin
var
aItem := lst1.ListItems[I];
(aItem.FindComponent('lblTest') as TLabel).Text := 'Changed';
end;
finally
lst1.EndUpdate;
end;
编辑:
由于 rctg
是您标签的父级,因此您将使用以下内容:
(rctg.FindComponent('lblTest') as TLabel).Text := 'Changed';
在提出这样的问题时,最好提供一个简化版本的代码,这样更容易理解。但是,我相信以下内容应该有用。 (我只在 Windows 上试过,未在 Android 上试过,但我不认为这会有所作为。)
首先,您的搜索代码存在问题,因为您使用相同的循环变量 (i
) 来获取两个不同的控件。也就是说,当您获得第一个项目时,您正在寻找该项目中的第一个组件,而在第二个项目中,您正在寻找第二个组件,依此类推。您需要单独的循环变量。
只要您搜索的是正确的列表框,那么您从其他表单搜索应该没有什么区别。
我没有尝试使用 .Components[]
属性,因为它可以包含 non-control 组件,而您只需要 TLabel
s,它们是控件。但是,我不明白为什么这也行不通。
我下面的代码并没有完全复制您的 search-and-replace 目标,因此您当然必须对其进行调整。在我的列表中,我将标签命名为 'value0_'+n.ToString
,其中 n
只是列表项中的 n-th 标签。所以你必须相应地调整它。
procedure TForm1.ChangeLabels;
var Item: TListBoxItem;
i,j: Integer;
Ctrl: TControl;
Lbl: TLabel absolute Ctrl;
begin
for i:=0 to ListBox1.Count-1 do begin
Item:=ListBox1.ListItems[i];
for j:=0 to Item.ControlsCount-1 do begin
Ctrl:=Item.Controls[j];
if Ctrl is TLabel then begin
if Lbl.Name='value0_3' then Lbl.Text:='CHANGED IT!';
if Lbl.Name='value0_4' then Lbl.Text:='Another one!';
end;
end;
end;
end;