FAQ VCL
Компоненты\VirtualTreeView

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как полностью развернуть TVirtualTreeView?

VirtualStringTree1.FullExpand( nil );


Как полностью свернуть TVirtualTreeView?

VirtualStringTree1.FullCollapse( nil );


Как выделить нод в TVirtualTreeView?

VirtualStringTree1.Selected[Node] := true; // false для снятия выделения
// Node - PVirtualNode, нод, который нужно выделить


Как получить абсолютный индекс нода в TVirtualTreeView?

VirtualStringTree1.AbsoluteIndex( Node );


Как получить уровень (Level) нода в TVirtualTreeView?

VirtualStringTree1.GetNodeLevel( Node );


Как скрыть/показать нод в TVirtualTreeView?

// Скрыть нод
procedure TForm1.Button1Click(Sender: TObject);
begin
   SelectNode.States := SelectNode.States + [vsHidden];
   VirtualStringTree1.Invalidate;
end;

// Показать нод
procedure TForm1.Button2Click(Sender: TObject);
begin
   SelectNode.States := SelectNode.States - [vsHidden];
   VirtualStringTree1.Invalidate;
end;

// SelectNode - нод, который нужно скрыть/показать


Как скрыть/показать нод со всеми дочерними нодами в TVirtualTreeView?

// Способ первый
// Скрыть нод
procedure TForm1.Button1Click(Sender: TObject);
begin
   SelectNode.States := SelectNode.States - [vsVisible];
   VirtualStringTree1.Invalidate;
end;

// Показать нод
procedure TForm1.Button2Click(Sender: TObject);
begin
   SelectNode.States := SelectNode.States + [vsVisible];
   VirtualStringTree1.Invalidate;
end;

// Способ второй
// Скрыть нод<
procedure TForm1.Button1Click(Sender: TObject);
begin
   VirtualStringTree1.FullyVisible[SelectNode] := false;
end;

// Показать нод
procedure TForm1.Button2Click(Sender: TObject);
begin
   VirtualStringTree1.FullyVisible[SelectNode] := true;
end;

// Способ третий
// Скрыть нод
procedure TForm1.Button1Click(Sender: TObject);
begin
   VirtualStringTree1.IsVisible[SelectNode] := false;
end;

// Показать нод
procedure TForm1.Button2Click(Sender: TObject);
begin
   VirtualStringTree1.IsVisible[SelectNode] := true;
end;

// SelectNode - нод, который нужно скрыть/показать


Как изменить высоту выделенного нода в TVirtualTreeView?

// Способ первый
// Проверен в версии 5.1
// VirtualStringTree1.TreeOptions.MiscOptions.toVariableNodeHeight = True,
// хотя это спорный момент, при перерисовке дерева при включенном флаге
// VirtualStringTree1.TreeOptions.MiscOptions.toVariableNodeHeight бывают глюки.

procedure TForm1.VirtualStringTree1MeasureItem(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer);
begin
   if vsSelected in Node.States then
      NodeHeight := VirtualStringTree1.DefaultNodeHeight * 2
   else
      NodeHeight := VirtualStringTree1.DefaultNodeHeight;
end;

// Способ второй
// Проверен в версии 5.5.3 (т.к. первый способ в этой версии не работает)
// Как и в первом способе флаг toVariableNodeHeight не включаем.
procedure TForm1.VirtualStringTree1FocusChanging(Sender: TBaseVirtualTree;
  OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex;
  var Allowed: Boolean);
begin
   if  NewNode <> OldNode then
   begin
      VirtualStringTree1.NodeHeight[NewNode] := VirtualStringTree1.DefaultNodeHeight * 2;
      VirtualStringTree1.NodeHeight[OldNode] := VirtualStringTree1.DefaultNodeHeight;
   end;
end;


Как реализовать фильтрацию нодов в TVirtualTreeView (скрыть ноды, не соответствующие фильтру)?

type
  // Данные, прикрепленные к узлу
  PRec = ^TRec;
  TRec = record
    Name: string; // Caption нода
    // Могут быть и другие параметры
  end;

  PTreeSearch = ^TTreeSearch;
  TTreeSearch = record
    ClearSearch: boolean;
    Name: string;
  end;
  
// Рекурсивный обход дерева
procedure FindInTree( Tree: TVirtualStringTree; Node: PVirtualNode;
  Search: TTreeSearch; var Hide: boolean );
var
  p: PRec;
  flag, recurse: boolean;
begin
   flag := false;
   repeat
      if Tree.GetNodeLevel( Node ) = 0 then
         flag := false;

      recurse := false;
      p := Tree.GetNodeData( Node );
      if Assigned( p ) then
      begin
         if Search.ClearSearch then
            Hide := false
         else
            // Проверка на соответствие фильтру
            Hide := Pos( AnsiLowerCase( Search.Name ), AnsiLowerCase( p^.Name ) ) = 0;
         if not Hide then
            flag := true;

         if ( Node.ChildCount > 0 ) and ( Tree.GetFirstChild( Node ) <> nil ) then
         begin
            recurse := true;
            FindInTree( Tree, Tree.GetFirstChild( Node ), Search, Hide );
         end;

         if flag and recurse then
         begin
            Node.States := Node.States - [vsHidden];
            flag := true;
         end
         else
            if Hide then
               Node.States := Node.States + [vsHidden]
            else
               Node.States := Node.States - [vsHidden];

         Node := Node.NextSibling;
      end;
   until Node = nil;
   if flag then
      Hide := false;
end;

// Пример вызова процедуры
procedure TForm1.Button1Click(Sender: TObject);
var
  ts: TTreeSearch;
  Hide: boolean;
begin
   case Length( Edit1.Text ) of
      0: begin
         ts.ClearSearch := true;
      end;
      else
      begin
         ts.ClearSearch := false;
         ts.Name := Edit1.Text;
      end;
   end;
   FindInTree( VirtualStringTree1, VirtualStringTree1.GetFirstChild( nil ), ts, Hide );
   VirtualStringTree1.Invalidate;
end;

// P.S.
// Обнаружен неприятный баг у VirtualStringTree версии 4.8.6
// После скрытия/отображения узла сбивается максимальное значение у вертикального скролла.
// Способа исправить этот баг найти не удалось. Тестировалось на Delphi 2010.
// Тест на Delphi 2007 с VirtualStringTree версии 4.7.0 такой проблемы не выявил.


Как реализовать автоматическую прокрутку к выбранному элементу в TVirtualTreeView?

VirtualStringTree1.ScrollIntoView( Node, true );
// Node - нод, до которого нужно прокрутить VirtualTreeView

При использовании материала - ссылка на сайт обязательна