Firemonkey TListBox.OnClick — какой элемент нажат?

Delphi 10.2.2 для мобильных устройств

Начиная с пустого мобильного проекта, я добавляю в форму TListBox. Я добавляю два TListBoxItems.

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  ShowMessage('ListBoxItem.itemindex = ' + ListBox1.ItemIndex.ToString);
end;

Когда я нажимаю на первый элемент в Windows и Macintosh, OnClick() правильно сообщает, что был нажат элемент с индексом 0.

Когда я нажимаю на первый элемент на мобильном устройстве (iOS и Android), OnClick() сообщает об индексе элемента как -1 (а не 0, как следует). Затем он продолжает выделять первый элемент.

Если я затем нажму на второй элемент на мобильном телефоне, OnClick() сообщит об индексе элемента как 0 (а не 1, как следует). Затем он продолжает выделять второй элемент.

Как я могу получить правильный элемент в OnClick() при нажатии в TListBox на мобильном телефоне?


person Mike at Bookup    schedule 15.02.2018    source источник
comment
Это похоже на ошибку, о которой нужно сообщить в Emba.   -  person David Heffernan    schedule 15.02.2018
comment
quality.embarcadero.com/browse/RSP-19266   -  person Mike at Bookup    schedule 16.02.2018
comment
Несмотря на ошибку: есть ли проблема с использованием OnItemClick?   -  person Dave Nottage    schedule 18.02.2018
comment
Просто используйте событие OnChange, оно передает элемент, который был выбран/щелкнут, и вызывается ПОСЛЕ обновления ItemIndex.   -  person Hans    schedule 19.02.2018
comment
Проблема с OnItemClick заключается в том, что он оставляет элемент выделенным даже после того, как список был очищен и заменен новыми вариантами выбора.   -  person Mike at Bookup    schedule 19.02.2018
comment
Событие OnChange запускается, когда код добавляет элементы в список. Это бесполезно, если нужно просто иметь событие, когда элемент выбирается пользователем.   -  person Mike at Bookup    schedule 19.02.2018


Ответы (1)


Очевидно, что событие OnClick запускается до обновления ItemIndex. Таким образом, вам придется отложить обработку до тех пор, пока ItemIndex не получит шанс обновиться первым. Ты сможешь:

  • используйте TThread.ForceQueue() (только 10.2 Tokyo+):

    procedure TForm1.ListBox1Click(Sender: TObject);
    begin
      TThread.ForceQueue(nil,
        procedure
        begin
          ShowMessage('ListBoxItem.itemindex = ' + ListBox1.ItemIndex.ToString);
        end
      );
    end;
    
  • используйте TThread.Queue():

    procedure TForm1.ListBox1Click(Sender: TObject);
    begin
      TThread.CreateAnonymousThread(
        procedure
        begin
          TThread.Queue(nil,
            procedure
            begin
              ShowMessage('ListBoxItem.itemindex = ' + ListBox1.ItemIndex.ToString);
            end
          );
        end
      ).Start;
    end;
    
  • используйте короткий таймер:

    procedure TForm1.ListBox1Click(Sender: TObject);
    begin
      Timer1.Enabled := True;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      Timer1.Enabled := False;
      ShowMessage('ListBoxItem.itemindex = ' + ListBox1.ItemIndex.ToString);
    end;
    
person Remy Lebeau    schedule 15.02.2018
comment
Я надеялся найти способ просмотреть значение, которое будет присвоено ItemIndex, но метод таймера работает достаточно хорошо. - person Mike at Bookup; 16.02.2018