Virtual Treeview jsem již uváděl v přehledu zajímavých komponent pro Delphi. Abych se přiznal, tak tuto komponentu považuji za jednu z nejlepších co pro Delphi existují a navíc se jedná o Open Source kód. Dá se použít jako pekelně rychlý strom nebo něco jako ListView nebo kombinace obojího a nebo prostě cokoli.
Výsledkem dnešního cvičení bude v podstatě minimální základ pro reálné použití VT. Jednoúrovňový strom s pozadím a více sloupci (konkrétně dvěma) - viz obrázek.

Výsledný program za běhu
Ještě než začneme tak jen upozorním, že přidání cca 1 mil. uzlů na průměrném současném počítači trvá kolem 1s.
Program byl s ohledem na majitele starších verzí Delphi napsán na Delphi 5, ale není problém aby fungoval na Delphi 2010. Ještě ke kompatibilitě komponenty: aktuální verze je VT 5 a něco a ta je kompatibilní s Delphi 7+, ale kolem verze 4.8 byla podpora i pro Delphi 5 a zároveň i s unicode Delphi, což je optimální pokud portujete starší projekt (nejdříve upgradujete všechny komponenty v původní verzi Delphi a pak teprve provedete switch).
Založíme nový projekt a na formulář vložíme TVirtualStringTree s názvem vt, jeden edit box (edtNodeCountEdit), tlačítko a TLabel (lblSelected). Rozdíl proti TVirtualDrawTree je v lepší podpoře pro práci s řetězci, ale pokud chcete úplnou kontrolu nad kreslením položek tak neváhejte a zvolte TVirtualDrawTree.
Nyní nastavíme pár property u stromu (sice by to šlo za běhu, ale nebudeme to komplikovat):
- DblClickem se zobrazí editor sloupců, kde přidáme dva sloupce se šířkami 150 pixelů (a nezapomeneme nastavit Text, což je text v záhlaví).
- v TreeOptions je podsekce SelectionOptions a tam nastavíme Multiselect popř. jiné
- v Header.Options nastavíme hoVisible na True (ukáže se záhlaví sloupců)
- SelectionCurveRadius nastavíme na 5 (zaoblení výběru)
- v sekci Colors se můžeme vyřádit dle libosti
- v Background načteme pozadí (viz níže) a v TreeOptions.PaintOptions nastavíme toShowBackground na true

Pozadí pro program
To je tak všechno pro tuto chvilku, ale zdaleka ne co se dá s VT nastavovat. Klidně si zkuste nastavovat různé Options, je jich tam mraky.
Nyní přejdeme na kód. Nejdříve deklarujeme strukturu, v které budeme uchovávat naše data pro zobrazení ve stromu.
1type
2 TMyNodeData = record
3 iCommission: Integer;
4 crPrice: Currency;
5 end;
6 PMyNodeData = ^TMyNodeData;
Nyní musíme říct VT velikost naší struktury, aby mohl pro jednotlivé uzly alokovat paměť a to obsloužením GetNodeDataSize. Nebo to jde udělat i za běhu nastavením NodeDataSize třeba ve FormCreate.
1procedure TfrmVTtest.vtGetNodeDataSize(Sender: TBaseVirtualTree;
2 var NodeDataSize: Integer);
3begin
4 NodeDataSize := SizeOf(TMyNodeData)
5end;
Další na řadě je inicializace jednotlivých uzlů a to buďto obsloužením OnInitNode nebo za běhu.
1procedure TfrmVTtest.vtInitNode(Sender: TBaseVirtualTree; ParentNode,
2 Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
3var
4 MyNodeData:PMyNodeData;
5begin
6 MyNodeData := Sender.GetNodeData(Node);
7 MyNodeData^.iCommission := Node.Index;
8 MyNodeData^.crPrice := Random(1000);
9end;
Nyní obsluha tlačítka.
1procedure TfrmVTtest.AddButtonClick(Sender: TObject);
2var
3 iCount: Integer;
4begin
5 Screen.Cursor := crHourGlass;
6 with vt do
7 try
8 iCount := StrToInt(edtNodeCountEdit.Text);
9
10
11 RootNodeCount := Integer(RootNodeCount) + iCount;
12 finally
13 Screen.Cursor := crDefault;
14 end;
15end;
Tak teď už jen co se bude zobrazovat. Pro teď nebudeme řešit ikony nebo speciální kreslení - jen získání textu v OnGetText.
1procedure TfrmVTtest.vtGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2 Column: TColumnIndex; TextType: TVSTTextType;
3 var CellText: WideString);
4var
5 MyNodeData:PMyNodeData;
6begin
7 MyNodeData := Sender.GetNodeData(Node);
8 with MyNodeData^ do
9 begin
10 case Column of
11 0: CellText := 'Zakázka: '+IntToStr(iCommission);
12 1: CellText := FloatToStr(crPrice);
13 end;
14 end;
15end;
A informaci o vybraných uzlech při změně atd. lze získat v OnChange
1procedure TfrmVTtest.vtChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
2begin
3 lblSelected.Caption := Format('Vybráno: %d', [vt.SelectedCount]);
4end;
A to je vše, jedná se opravdu minimální demo. Zdrojové kódu ke stažení zde (13 KB). Jinak k VT je dostupné na stránkách autora velké demo (včetně zdrojových kódů), které opravdu stojí za pozornost.