Home > database >  Search for a Label which created on runtime in android app in Delphi
Search for a Label which created on runtime in android app in Delphi

Time:05-17

In an android app, in a ListBox i'm creating ListBoxItems, into each Item a reactangle and into each rectangle i'm ctreating 5 labels all this dynamically in RUN TIME, 5 labels for each Listboxitem created. The only unique property of the labels is the name who changes for each listboxitem that created. Now, i can't find a way to find a specific label to change its text property. I can find in which Listboxitem and by extension which rectangle is the Label i want ( with tag_num variable) but i cant determine the specific label to change its text.

the code of creatig the 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; 

and so on... It is possible to created from 1 ListBoxItem to 15 or more.. How to change, for example the lb1 Label in 10th lIstBoxItem, its text? I find a similar problem here Search for a Label by its Caption but doesnt work for me.. Any ideas?

my search code is :

  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;

i'll should mention that the search takes place in another form of where the ListBox is created.

CodePudding user response:

This is actually rather simple but your method seems to be a lot more complicated than it should be.

When you dynamically create a TlistboxItem and then create a TLabel and set the TLisboxItem you created as owner the label doesnt need a unique name. It will need to be unique to the Item but not globally.

Example: You cannot dynamically create 2 labels in the same item with the same names but you can use the same name in 2 different items.

Example for creating new Listbox items with labels:

// 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;

Example for changing those dynamic labels in the listboxitems:

// 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;

EDIT: Since rctg is the parent of your label you will use the following:

(rctg.FindComponent('lblTest') as TLabel).Text := 'Changed';

CodePudding user response:

In asking questions like this, it's best to give a simplified version of your code, as it makes it easier to understand. However, I believe that the following should be useful. (I've only tried this on Windows, not Android, but I wouldn't expect that to make a difference.)

First, your search code has a problem in that you are using the same loop variable (i) for getting two different controls. That is, when you get the first item, you're looking for the first component in that item, and in the second item, you're looking for the second component, and so on. You need separate loop variables.

That you are searching from another form should make no difference, as long as you are searching the correct list box.

I didn't try using the .Components[] property, as that can include non-control components, and you are only wanting TLabels, which are controls. However, I don't see why that shouldn't work too.

My code below does not replicate your exact search-and-replace goals, so you'll have to adapt it of course. In mine, I named the labels 'value0_' n.ToString where n is simply the n-th label in the list item. So you'll have to adjust that accordingly.

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;

  • Related