Перейти к содержанию
Fire Monkey от А до Я
  • 0

При добавлении итемов в TListBox из события OnViewportPositionChange, ViewportPosition всегда смещается в начало


A. Sharif

Вопрос

Delphi 10.1. Кроссплатформ, задачка следующая: 

Необходимо добавлять определенное количество итемов в начало списка TListBox. Причем ViewportPosition при этом меняться не должно (т.е. область скролла не должна смещаться, если ViewportPosition не корректировать - все смещается). Если реализовать данную процедуру при клике на кнопку - все работает.

Если реализовать из события OnViewportPositionChange таким образом, чтобы при прокручивании списка почти к началу (когда ViewportPosition.Y станет < 100, например) добавлялись новые итемы - не работает, всегда VP сбрасывается в начало. Как это побороть? Пробовал различные варианты с сохранением значений старой VP, откладыванием на время добавление итемов через поток и пр. - не помогло.

Ниже код программы, нужно просто создать новый проект, добавить TListBox и пару кнопок, сопоставить события. Сначала нажимаем button1, затем начинаем подкручивать список к началу, чтобы добавить новые итемы. По button2 также можно добавить новые итемы.

procedure TForm1.AddItems(Anum: integer);
var
  I: integer;
  h,dy : single;
begin
    h := ListBox1.ContentBounds.Height;
    for I := 0 to Anum do begin
        ListBox1.Items.Insert(0,'итем № '+inttostr(ListBox1.Count));
    end;
    dy := ListBox1.ContentBounds.Height-h;
    ListBox1.ScrollBy(ListBox1.ViewportPosition.X,-dy);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
     AddItems(50);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     AddItems(100);
     ListBox1.ScrollToItem(ListBox1.ItemByIndex(99));
     ListBox1.OnViewportPositionChange := ListBox1ViewportPositionChange;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
    t : TThread;
begin
     with ListBox1.AniCalculations do begin
         Animation := true;
         BoundsAnimation := true;
         TouchTracking := [ttVertical];
     end;
end;

procedure TForm1.ListBox1ViewportPositionChange(Sender: TObject;
  const OldViewportPosition, NewViewportPosition: TPointF;
  const ContentSizeChanged: Boolean);
var
    thread: TThread;
begin
     if NewViewportPosition.Y <= 100 then begin
         ListBox1.OnViewportPositionChange := nil;
         Button2Click(sender);
     end;
end;

P.S. В событии OnViewportPositionChange ВСЕГДА приходит ContentSizeChanged = true.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
2 часа назад, A. Sharif сказал:

Ниже код программы, нужно просто создать новый проект, добавить TListBox и пару кнопок, сопоставить события. Сначала нажимаем button1, затем начинаем подкручивать список к началу, чтобы добавить новые итемы. По button2 также можно добавить новые итемы.

Никто не будет создавать новый проект и тем более, что то сопоставлять...

Приложите проект.

Ссылка на комментарий
  • 0

Кажется, ответ нашел сам. ViewportPosition в данном случае устанавливается как надо только если использовать ListBox1.ViewportPosition := TPointF.Create(X,Y) после добавления всех итемов.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...