AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte TreeView mit Find und Filter
Thema durchsuchen
Ansicht
Themen-Optionen

TreeView mit Find und Filter

Ein Thema von taaktaak · begonnen am 12. Mär 2008 · letzter Beitrag vom 14. Mär 2008
Antwort Antwort
taaktaak
Registriert seit: 25. Okt 2007
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!
Angehängte Dateien
Dateityp: zip test3_468.zip (233,3 KB, 46x aufgerufen)
 
Benutzerbild von Aurelius
Aurelius

 
Delphi 7 Personal
 
#2
  Alt 13. Mär 2008, 07:41
Hi taaktaak.

1.) die Suche findet gar nix
2.) wenn man mit rechts auf ein item klickt sollte das auch markiert werden
Jonas
  Mit Zitat antworten Zitat
taaktaak

 
Delphi 7 Professional
 
#3
  Alt 13. Mär 2008, 11:35
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.
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Aurelius
Aurelius

 
Delphi 7 Personal
 
#4
  Alt 13. Mär 2008, 12:02
Das geht doch, ich hab nicht gewusst dass der der genaue Begriff gesucht wird
Jonas
  Mit Zitat antworten Zitat
taaktaak

 
Delphi 7 Professional
 
#5
  Alt 13. Mär 2008, 12:28
Hallo xX0815Xx
aber auch die Suche mit Wildcards sollte immer funktionieren - oder?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Aurelius
Aurelius

 
Delphi 7 Personal
 
#6
  Alt 13. Mär 2008, 12:41
Ja, das funktioniert einwandfrei

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
Jonas
  Mit Zitat antworten Zitat
taaktaak

 
Delphi 7 Professional
 
#7
  Alt 13. Mär 2008, 15:14
Ja, das ist kein Problem, kommt heute Abend
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Aurelius
Aurelius

 
Delphi 7 Personal
 
#8
  Alt 13. Mär 2008, 15:17
Super von dir
Jonas
  Mit Zitat antworten Zitat
taaktaak

 
Delphi 7 Professional
 
#9
  Alt 13. Mär 2008, 18:46
Moin, Moin xX0815Xx,
hier mal der relevante Ausschnitt der Suchprozedur...

Delphi-Quellcode:
.
..
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 ...
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.


Die Funktion MatchStr() ist für den Zeichenkettenvergleich (incl. WildCards) zuständig.

Delphi-Quellcode:
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;
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.

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.
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Aurelius
Aurelius

 
Delphi 7 Personal
 
#10
  Alt 14. Mär 2008, 07:28
Danke, ich werds mir mal zu Gemüte führen
Jonas
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz