Filtrování Virtual Tree View

vložil Radek Červinka 24. října 2012 22:36

Moc se mi líbí způsob vyhledávání ala Windows 7 nebo novější Delphi IDE, tj. začnete psát a zobrazují se vám jen relevantní záznamy. Přemýšlel jsem, jak je to těžké udělat pro můj milovaný švýcarský nůž mezi komponentami aka TVirtualTreeView. Jelikož právě v Delphi IDE je použit modifikovaný VirtualTreeView tak jsem doufal, že to až takový problém nebude. A nebyl.

Virtual TreeView

Předpokládám, že máte přečteny minulé díly seriálu o VT - jsou dostupné přes tag na konci článku.

Uzel stromu (tedy PVirtualNode) má kromě jiných možných stavů i stav vsFiltered, který se nastavuje a (nejlépe) zjišťuje přes property stromu IsFiltered … a to je v podstatě vše - zbytek zařídí VT.

Následující kód rekurzivně projde strom a nechá zobrazené jen ty uzly, co obsahují filtr (na obrázku jen s "zá"). Je to část většího kódu a nechtěl jsem to moc upravovat - proto se některé části dají napsat kratší.

PVTNavigatorRec je v mém případě record obsahující virtuální data - viz minulé díly. U vás to bude něco jiného.

Volání (vt je strom) je pak:

  mUpdateFilter(vt.RootNode, AnsiUppercase(Trim(edtSearch.Text)));

Jen bych upozornil na řádek 41 a 45, kdy v prvním případě je porovnání, v druhém pak zajištění, že celá cesta k uzlu bude rozbalena.

    1procedure TfrmNavigator.mUpdateFilter(pParentNode:PVirtualNode; const sFilter: string);
    2var
    3  pNode: PVirtualNode;
    4  pNodeData: PVTNavigatorRec;
    5  sText: string;
    6  bChildrenVisible: Boolean;
    7  b: Boolean;
    8
    9  function mbAreChildrenVisible(pParent:PVirtualNode):Boolean;
   10  var
   11    p: PVirtualNode;
   12  begin
   13    p := pParent.FirstChild;
   14    Result := False;
   15    while p <> nil do
   16    begin
   17      Result := not vt.IsFiltered[p];
   18      if Result then
   19        Exit;
   20      p := p.NextSibling;
   21    end;
   22  end;
   23begin
   24  if (pParentNode = nil) or (pParentNode.ChildCount = 0) then
   25    Exit;
   26  pNode := pParentNode.FirstChild;
   27  while pNode <> nil do
   28  begin
   29    if pNode.ChildCount <> 0 then
   30    begin
   31      mUpdateFilter(pNode, sFilter);
   32      bChildrenVisible := mbAreChildrenVisible(pNode);
   33      vt.IsFiltered[pNode] := not bChildrenVisible;
   34    end
   35    else
   36    begin
   37      if sFilter <> '' then
   38      begin
   39        pNodeData := vt.GetNodeData(pNode);
   40        sText:= pNodeData^.sCaption;
   41        b := AnsiPos(sFilter, AnsiUppercase(sText)) = 0;
   42        vt.IsFiltered[pNode] :=  b;
   43        if not b then
   44        begin
   45          vt.VisiblePath[pNode] := True;
   46        end;
   47      end
   48      else
   49        vt.IsFiltered[pNode] := False;
   50    end;
   51    pNode := pNode.NextSibling;
   52  end;
   53end;

Podle mne to opět dokazuje jak je VT perfektní navržený nástroj.


Nabízíme Delphi školení na různá témata, primárně ve Vaší firmě.

Tagy: ,

Praxe

Komentáře

25.10.2012 2:10:33 #

TLama

Jenom dodám, že existuje hodnota enumerace toShowFilteredNodes, která když se přidá do setu TreeOptions.PaintOptions, zobrazí se i větve, které jsou vyfiltrované; pokud se z něj tato hodnota odebere, zase se schovají. To se dá v praxi použít např. jako "cache" pro funkci typu "zobrazit vše / zobrazit filtrované".

Jinak v případě, kdy se filtruje pouze několik položek stromu (což je případ výše uvedený) kdy to význam nemá, v řádu stovek je to ještě v pohodě, ale u stovek tisíců položek bych už určitě přemýšlel o incremental filtru; tedy, pokud se na konci filtračního textu objeví nový znak (nebo znaky), projdou se už jenom větve, které nejsou aktuálně vyfiltrované a ne celý strom, jako se děje v uvedeném příkladu.

TLama

25.10.2012 9:55:44 #

Radekc

toShowFilteredNodes jsem zapomněl uvést - dobré připomínky, díky.

Radekc

31.10.2012 12:51:35 #

Marek Rakowski

super příklad

díky

Marek Rakowski

10.6.2013 14:18:11 #

JBD

Neměl bys prosím ještě nějaké příklady (s vysvětlením) této komponenty? (např DB)
Prošel sem si demo, ale nejsem z toho moc chytrý...

=c((

Dík

JBD

10.6.2013 16:44:17 #

radekc

Pod článkem jsou tagy, a jeden z nich je překvapivě Virtual TreeView. To ti nestačí?

radekc

11.6.2013 0:00:56 #

JBD

Ne, nebylo to překvapení. Všechny čtyři články o Virtual TreeView, co jsou tu k nalezení, jsem si několikrát přečetl, příklady jsem zprovoznil, jen jsem úplně nepochopil to plnění dat. V příkladech používáš jako data údaje konkrétního nodu, ale pomohla by mi třeba ukázka dat z tabulky - třeba 1:N =c))
Vím, že je tu spousta lidí co by po Tobě chtěli, aby jsi za ně udělal jejich práci bez námahy. Jenže já s tím zápasím už hodně dlouho a tohle jsem zatím nebyl schopen pochopit.

Díky

JBD

21.8.2013 17:09:50 #

Martin

Zdravím VirtualTreeViewisty, každy kdo pracuje s touto komponentou jásá, ale já jsem z toho taky trochu mimo, prošel sem několik příkladů, ale stále nechápu... má někdo nebo je nědke na webu návod pro trubky? :-D
Díky

Martin

21.8.2013 18:39:52 #

radekc

Zkoušel jsi kliknout na tag virtual tree view?

radekc

Komentování ukončeno

Naše nabídka

Partial English version.

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 nebo burzy práce).

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 (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

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.

Anketa

Poslední komentáře

Comment RSS