Необходимо добавлять определенное количество итемов в начало списка 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.
Вопрос
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.
Ссылка на комментарий
3 ответа на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.