ListBox items change after doing scroll in Firemonkey

对着背影说爱祢 提交于 2019-12-01 10:39:15

问题


I am developing a Multi-Device Application in Firemonkey where Main class has a ListBox component with some items. Each of these items has the same custom style.

My problem is when I have so many items in the ListBox and I have to do scroll vertical to see the rest of items. In this case, the ListBox has a strange behaviour and when I do scroll up after doing scroll down the item's components (a button for example) have changed his background colour and the items have changed his order inside ListBox.

For example, if I had:

  1. Item 1
  2. Item 2
  3. Item 3

after I do scroll I have:

  1. Item 2
  2. Item 3
  3. Item 1

This change is random. Each time is different.

Real example (process steps):

  1. Load the Main class where is ListBox.

  1. Do vertical scrolling down to see the rest of items.

  2. Do vertical scrolling upward to return to the top of the list.

  1. The items have changed position in the ListBox and the button (component of each item) changes its background color.

Why I have this behaviour in the ListBox?? How I can solve it and the ListBox do not change items order neither background colour of his components?

I do not know if there is any property to block items inside ListBox or similar ...

EDIT

This is the code to create and initialize the ListBox items:

procedure TRooms_Form.FormCreate(Sender: TObject);
var
  ...
begin
    i := 0;
    while i < numItems do begin
      //Create ListBox item
       item := TListBoxItem.Create(nil);
       item.Parent := myListBox;
       item.StyleLookup := 'styleLBox';
      //Number
       itemNumber := item.FindStyleResource('btt_number') as TButton;
       if Assigned(itemNumber) then begin
           itemNumber.Text := jsonNumber;
           case jsonColor of
             0 : itemNumber.TintObject.TintColor := TAlphaColors.Chocolate; 
             1 : itemNumber.TintObject.TintColor := TAlphaColors.Gold;      
             2 : itemNumber.TintObject.TintColor := TAlphaColors.Darkgreen; 
             3 : itemNumber.TintObject.TintColor := TAlphaColors.Deeppink;  
           end;
         end;
      //Title
       itemTitle := item.FindStyleResource('txtstyle_title') as TText;
       if Assigned(itemTitle) then begin
         itemTitle.Text := jsonTitle;
       end;
      //Occupation
       itemOccup := item.FindStyleResource('txt_occupation') as TText;
       if Assigned(itemOccup) then begin
         itemOccup.Text := jsonOccup;
       end;
      //Dates
       itemDay := item.FindStyleResource('txt_day') as TText;
       if Assigned(itemDay) then itemDay.Text := displayDay;
       itemDateStart := item.FindStyleResource('txt_start') as TText;
       if Assigned(itemDateStart) then itemDateStart.Text := jsonTimeStart;
       itemDateEnd := item.FindStyleResource('txt_end') as TText;
       if Assigned(itemDateEnd) then itemDateEnd.Text := jsonTimeEnd;
      //Item background
       itemBackgr := item.FindStyleResource('background_item') as TRectangle;
       if Assigned(itemBackgr) then begin
         itemBackgr.Fill.Kind := TBrushKind.Solid;
         case jsonStatus of
           0 : itemBackgr.Fill.Color := TAlphaColors.White;         
           1 : itemBackgr.Fill.Color := TAlphaColors.Lightgreen;    
           2 : itemBackgr.Fill.Color := TAlphaColors.Palegoldenrod; 
           3 : itemBackgr.Fill.Color := TAlphaColors.Lightcoral;    
           4 : itemBackgr.Fill.Color := TAlphaColors.Lightseagreen; 
           5 : itemBackgr.Fill.Color := TAlphaColors.Lightblue;     
           6 : itemBackgr.Fill.Color := TAlphaColors.Lightgrey;     
         end;
       end;
      //Empty item
       if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
         startDetail[i] := False;
         if Assigned(itemNumber) then itemNumber.Visible := False;
         if Assigned(itemOccup) then itemOccup.Visible := False;
       end
       else begin
         startDetail[i] := True;
       end;

       Inc(i);
    end;

Thanks so much for your attention.


回答1:


After some days and some tests, I have already found a solution to my problem.

I do not understand well why but there was some code lines that they were interfering with my custom style.

For example, when I put:

//Item background
   itemBackgr := item.FindStyleResource('background_item') as TRectangle;
   if Assigned(itemBackgr) then begin
     **itemBackgr.Fill.Kind := TBrushKind.Solid;**
     ...

After scroll, items changed order position and their color background. I have applied this property directly in the 'TRectangle' component in the custom style.

Moreover, I changed the allocation of all elements to this way:

-Before I had:

   itemTitle := item.FindStyleResource('txtstyle_title') as TText;
   if Assigned(itemTitle) then begin
     itemTitle.Text := jsonTitle;
   end;

-Now, I have:

   item.StylesData['txtstyle_title'] := jsonTitle;

With these changes I get items do not change their position in ListBox neither background color after scroll.

I had a problem yet, buttons do not show their background color and it was due to these lines:

//Empty item
   if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
     startDetail[i] := False;
     **if Assigned(itemNumber) then itemNumber.Visible := False;**
     **if Assigned(itemOccup) then itemOccup.Visible := False;**
   end
   else begin
     startDetail[i] := True;
   end;

Apparently, you cannot change visible property from item in 'FormCreate' method because when you do scroll some items elements change their property without control. Therefore, I have done some modifications in my code instead of putting to false the visibility:

    if (StrToInt(jsonEmpty) = 1) or (StrToInt(jsonNull) = 1) then begin
      startDetail[i] := False;
      item.StylesData['btt_number.Text'] := '';
      item.StylesData['txt_occupation'] := '';
      if (StrToInt(jsonEmpty) = 1) then item.StylesData['btt_number.TintObject.TintColor'] := TAlphaColors.White;
      if (StrToInt(jsonNull) = 1) then item.StylesData['btt_number.TintObject.TintColor'] := TAlphaColors.Lightblue;
    end
    else begin
      startDetail[i] := True;
      item.StylesData['btt_number.Text'] := jsonNumber;
      item.StylesData['txt_occupation'] := jsonOccup;
    end;

At this form, I put the text ' ' (empty) and the background color at the same color that his item (TRectangle) in the elements who should to have the visible property to false.

After all these changes I get the result that I wanted, that is to say, my items ListBox do not change when I scroll. XD



来源:https://stackoverflow.com/questions/38219295/listbox-items-change-after-doing-scroll-in-firemonkey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!