Lehký úvod do Virtual TreeView

vložil Radek Červinka 20. ledna 2010 23:07

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á aplikace

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í

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.

type
  TMyNodeData = record
    iCommission: Integer; // cislo zakazky pro prvni sloupec
    crPrice: Currency;  // cena zakázky pro druhý sloupec
  end;
  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.

procedure TfrmVTtest.vtGetNodeDataSize(Sender: TBaseVirtualTree;
  var NodeDataSize: Integer);
begin
  NodeDataSize := SizeOf(TMyNodeData)
end;

Další na řadě je inicializace jednotlivých uzlů a to buďto obsloužením OnInitNode nebo za běhu.

procedure TfrmVTtest.vtInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
  MyNodeData:PMyNodeData;
begin
  MyNodeData := Sender.GetNodeData(Node); // získáme data pro uzel
  MyNodeData^.iCommission := Node.Index; // a pro ukázku nastavíme číslo zakázky
  MyNodeData^.crPrice := Random(1000);  // nějaká náhodná cena
end;

Nyní obsluha tlačítka.

procedure TfrmVTtest.AddButtonClick(Sender: TObject);
var
  iCount: Integer;
begin
  Screen.Cursor := crHourGlass;
  with vt do
  try
    iCount := StrToInt(edtNodeCountEdit.Text); //kolik uzlů přidat
// o tolik zvětšit počet uzlů z kořene, podobně i pro pod uzly, 
// postupně se bude volat OnInitNode
    RootNodeCount := Integer(RootNodeCount) + iCount; 
  finally
    Screen.Cursor := crDefault;
  end;
end;

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.

procedure TfrmVTtest.vtGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; 
  Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
  MyNodeData:PMyNodeData;
begin
  MyNodeData := Sender.GetNodeData(Node); // získej data pro uzel
  with MyNodeData^ do
  begin
     case Column of
      0: CellText :=  'Zakázka: '+IntToStr(iCommission); // první sloupec
      1: CellText := FloatToStr(crPrice);  // druhý sloupec
     end;
  end;
end;

A informaci o vybraných uzlech při změně atd. lze získat v OnChange

procedure TfrmVTtest.vtChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  lblSelected.Caption := Format('Vybráno: %d', [vt.SelectedCount]);
end;

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.

Tagy: , ,

Praxe

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS