TVirtualStringTree: Проблема со скроллингом при повторном вызове ScrollIntoView
При работе с виртуальным деревом (TVirtualStringTree) в Delphi может возникнуть проблема со скроллингом при повторном вызове функции ScrollIntoView. Если высота скроллируемого узла больше области клиента, первый вызов функции ScrollIntoView(GetLast, False, False) работает корректно и перемещает нас в конец последнего узла. Однако повторный вызов этой же функции приводит к перемещению в начало последнего узла, что нежелательно.
Пользователь, столкнувшийся с этой проблемой, обнаружил, что в коде функции ScrollIntoView есть условие if R.Top < 0, которое определяет, нужно ли скроллить вверх. При первом вызове R.Top равно 0, и выполнение переходит вelse-ветвь, что дает ожидаемый результат. Однако при втором вызове R.Top оказывается отрицательным, и выполняется if-ветвь, в результате чего происходит скроллинг к началу последнего узла.
Причина проблемы
Проблема заключается в том, что функция ScrollIntoView не предназначена исключительно для скроллинга к последнему узлу. Она используется для скроллинга к любому узлу, в том числе и к узлам, расположенным выше текущей области просмотра. При определенных условиях, таких как добавление новых узлов в реальном времени, функция может вести себя нестабильно и вызывать нежелательное перемещение.
Решение проблемы
Чтобы решить проблему, пользователь предложил использовать новый подход с помощью класс-хелперов в Delphi. Он создал класс-хелпер TBaseVirtualTreeHelper с процедурой ScrollToTheBottom, которая напрямую обращается к свойствам и методам виртуального дерева для скроллинга к последнему узлу.
Ниже приведен пример кода, который решает проблему без использования класс-хелперов:
procedure ScrollToTheBottom(VT: TBaseVirtualTree);
var
Node: PVirtualNode;
R: TRect;
begin
Node := VT.GetLast();
if Assigned(Node) and (Node <> VT.FRoot) then
begin
R := VT.GetDisplayRect(Node, NoColumn, True);
if (R.Bottom > VT.ClientHeight) then
VT.OffsetY := VT.OffsetY - R.Bottom + VT.ClientHeight;
end;
end;
Эта процедура принимает в качестве параметра экземпляр TBaseVirtualTree, получает последний узел и определяет, нужно ли скроллить вниз, чтобы полностью отобразить последний узел в области просмотра.
Заключение
При работе с виртуальным деревом в Delphi может возникнуть проблема со скроллингом при повторном вызове функции ScrollIntoView. Чтобы решить эту проблему, можно использовать альтернативный подход с помощью класс-хелперов или напрямую обращаться к свойствам и методам виртуального дерева, как в приведенном выше примере кода. Важно учитывать, что функция ScrollIntoView предназначена для скроллинга к любому узлу, а не только к последнему, и при определенных условиях может вести себя нестабильно.
При работе с виртуальным деревом (TVirtualStringTree) в Delphi может возникнуть проблема со скроллингом при повторном вызове функции ScrollIntoView, что приводит к нежелательному перемещению к началу последнего узла вместо его конца.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.