![]() |
TreeView mit Find und Filter
Liste der Anhänge anzeigen (Anzahl: 1)
Moin, Moin,
seit einigen Tagen bastle ich an einer Erweiterung von TCustomTreeView (ok, mir ist bekannt, dass es VirtualTreeView gibt - aber ich möchte einfach das TreeView besser kennen lernen). Die neuen Funktionalitäten bestehen aus einem "Standard-Popupmenü", das die Komponente jedem Programm zur Verfügung stellt. Integriert in dieses Popup sind 4 Funktionen, insbesondere "Find" und "Filter". Da ich jetzt langsam aber sicher betriebsblind werde, wäre es schön, wenn sich mal einer das angefügte Testprogramm vornimmt, das Popup testet und Verbesserungsvorschläge macht / Fehler aufspürt. Das Programm ist natürlich NUR zum Testen gedacht, es hat keinen praktischen Nutzen. Vorab schon mal ein herzliches Dankeschön! |
Re: TreeView mit Find und Filter
Hi taaktaak.
1.) die Suche findet gar nix 2.) wenn man mit rechts auf ein item klickt sollte das auch markiert werden |
Re: TreeView mit Find und Filter
Hallo xX0815Xx
vielen Dank für den Test! Allerdings merkwürdig, dass die Suche nichts findet. Das kann ich nicht reproduzieren. Sowohl bei Eingabe eines eindeutigen Suchtextes als auch bei Verwendung von WildCards funktioniert das mit der zur Verfügung gestellten Exe bei mir einwandfrei!? Nach welchem Begriff hast du gesucht? Die Markierung auch mit Rechtsklick kann natürlich zusätzlich vorgesehen werden. |
Re: TreeView mit Find und Filter
Das geht doch, ich hab nicht gewusst dass der der genaue Begriff gesucht wird :wall:
|
Re: TreeView mit Find und Filter
Hallo xX0815Xx
aber auch die Suche mit Wildcards sollte immer funktionieren - oder? |
Re: TreeView mit Find und Filter
Ja, das funktioniert einwandfrei :thumb:
Da ich im Augenblick selbst mit einer TreeView arbeite und diese auch durchsuchen möchte fände ich es toll wenn du die Suchprozedur veröffentlichen würdest :) |
Re: TreeView mit Find und Filter
Ja, das ist kein Problem, kommt heute Abend :thumb:
|
Re: TreeView mit Find und Filter
Super von dir :thumb:
|
Re: TreeView mit Find und Filter
Moin, Moin xX0815Xx,
hier mal der relevante Ausschnitt der Suchprozedur...
Delphi-Quellcode:
Der Prozedur wird das Suchmuster in "Pattern" und der Status der Checkbox in "CaseSensitive" übergeben. Wesentlich ist lediglich die Schleife, für jedes gefundene Item wird dessen TreeIndex in ein dynamisches Array abgelegt, damit dann mittels der beiden Buttons FindPrev FindNext alle Fundstellen angezeigt werden können. Dialog() ist eine spezielle Anzeigefunktion, also so was ähnliches wie ShowMessage(). Obwohl die Verwendung von TreeView.Items ziemlich langsam ist, ist die Geschwindigkeit auch bei mehreren tausend TreeItems noch akzeptabel.
.
.. SetHourglass(true); SetLength(FindList,0); for i:=0 to pred(TreeView~~.Items.Count) do if MatchStr(TreeView~~.Items[i].Text,Pattern,CaseSensitive) then begin SetLength(FindList,High(FindList)+2); FindList[High(FindList)]:=i end; SetHourglass(false); N:=High(FindList)+1; if N=0 then Dialog(1,-1,-1,1,-1, 'No matching tree item found ...', 'Ok','','','') else ... Die Funktion MatchStr() ist für den Zeichenkettenvergleich (incl. WildCards) zuständig.
Delphi-Quellcode:
An der Filterfunktion bastle ich übrigens noch. Da die TreeViewNodes keine Visible-Eigenschaft haben, müssen für die gefilterte Anzeige alle "nicht passenden" Nodes aus dem Tree entfernt werden. Das kann mit Item.Delete natürlich innerhalb einer Schleife ohne Aufwand realisiert werden - ist aber inakzeptabel langsam.
function MatchStr(Source,Pattern:String;CaseSensitive:Boolean):Boolean;
function Match(Source,Pattern:PChar):Boolean; begin if StrComp(Pattern,'*')=0 then Result:=true else if (Source^=Chr(0)) and (Pattern^<>Chr(0)) then Result:=false else if Source^=Chr(0) then Result:=true else case Pattern^ of '*': if Match(Source,@Pattern[1]) then Result:=true else Result:=Match(@Source[1],Pattern); '?': Result:=Match(@Source[1],@Pattern[1]); else if Source^=Pattern^ then Result:=Match(@Source[1],@Pattern[1]) else Result:=false; end; end; begin if not(CaseSensitive) then begin Source :=AnsiLowerCase(Source); Pattern:=AnsiLowerCase(Pattern); end; Result:=Match(PChar(Source),PChar(Pattern)) end; Zuerst hatte ich das Filtern dann mit einem Stream und einer Stringlist realisiert: Die Geschwindigkeit war daraufhin etwa 50-60 mal schneller. Das Vorgehen hatte aber den Nachteil, dass die "übrigen" Node-Informationen wie .ImageIndex, .SelectedIndex, .StateIndex und .Data verloren gingen. Ist natürlich ebenfalls nicht praktikabel. Derzeit werden diese Daten in einem zusätzlichen Record-Array "gerettet" und wiederhergestellt. Dadurch ist es wieder etwas langesamer, aber immer noch ausreichend schnell. Da das Ganze jetzt aber sehr "aufgebläht" ist, bastle ich derzeit an einer Lösung mit dem ObjectStream - der diese Informationen ja beinhaltet. Da es mir nicht gelungen ist, den Source der Speicherung gänzlich nachzuvollziehen, versuche ich derzeit das Schema der Binärdaten im Stream aufzuschlüsseln. Wenn das gelungen ist und das alles mit dem ObjectStream realisiert werden kann, werde ich den Source -sofern Interesse besteht- auch zur Verfügung stellen. |
Re: TreeView mit Find und Filter
Danke, ich werds mir mal zu Gemüte führen :)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz