Вопрос о скрытии определенных узлов в компоненте VirtualStringTree является актуальным для разработчиков, которые работают с большими объемами данных и стремятся повысить производительность своих приложений. В частности, при реализации функции фильтрации, когда VirtualStringTree используется как список с колонками, возникает необходимость избежать перезагрузки содержимого при изменении фильтра. Вместо этого, гораздо быстрее будет скрыть определенные элементы, не перерисовывая весь список.
Проблема и решение
Проблема, с которой сталкиваются разработчики, заключается в том, что стандартные методы фильтрации в VirtualStringTree требуют перерисовки и пересчета элементов, что существенно замедляет работу с большим количеством узлов. Однако, существует решение, позволяющее скрыть определенные узлы, не затрагивая остальные, что значительно ускоряет процесс фильтрации.
Подтвержденный ответ
Для скрытия узлов в VirtualStringTree используется свойство IsVisible[]. Пример кода на Object Pascal, который скрывает определенный узел:
VirtualTree.IsVisible[Node] := False;
Это свойство также корректирует общую высоту канваса дерева, благодаря чему вертикальная полоса прокрутки будет отражать скрытые узлы. Если же использовать метод Exclude(Node.States, vsVisible) или Node.States := Node.States - vsVisible, то канвас дерева не будет корректироваться, полоса прокрутки не изменится, и пользователь может столкнуться с большим количеством пустого пространства под последним отображаемым узлом.
Альтернативное решение
В случае, если использование .IsVisible[] или .IsFiltered[] является слишком медленным, например, при фильтрации 25 000 узлов, можно применить другой подход, заключающийся в изменении значения Node.TotalHeight в соответствии с количеством видимых узлов. Пример кода, который реализует данный подход:
procedure TFC_Articulo.Filtrar(Filtro: String);
var
Node: PVirtualNode;
Data: PArticulo;
begin
Node := TV.GetFirst;
TV.RootNode.TotalHeight := TV.DefaultNodeHeight;
while Assigned(Node) do
begin
Data := TV.GetNodeData(Node);
Exclude(Node.States, vsFiltered);
if ComparationHereForDetermineFiltering then
Include(Node.States, vsFiltered)
else
begin
Inc(TV.RootNode.TotalHeight, Node.NodeHeight);
Node.Visibile := True; // Устанавливаем узел видимым для корректного подсчета высоты
end;
Node := TV.GetNext(Node);
end;
TV.RootNode.TotalHeight := TV.RootNode.TotalHeight + TV.BottomSpace;
TV.UpdateScrollBars(True);
// Обновляем высоту для узлов, которые не скрыты свойством IsVisible
for var CurrentNode in TV.Nodes do
if CurrentNode.Visible then
IncResult(TV.RootNode.TotalHeight, CurrentNode.NodeHeight);
end;
При использовании данного подхода необходимо вручную управлять значением Node.TotalHeight, чтобы корректно отображать размер полосы прокрутки.
Заключение
Скрытие узлов в VirtualStringTree с помощью свойства IsVisible[] является эффективным способом реализации функции фильтрации без перезагрузки содержимого. Однако, для работы с большим количеством узлов может потребоваться альтернативный подход, включающий ручное управление свойством Node.TotalHeight. Оба метода позволяют избежать замедления работы приложения и обеспечивают пользователю комфортную работу с фильтрованными данными.
Вопрос касается технологии скрытия узлов в компоненте VirtualStringTree для оптимизации фильтрации данных без полной перезагрузки интерфейса.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS