Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi tree items zählen die rot markiert sind (https://www.delphipraxis.net/14764-tree-items-zaehlen-die-rot-markiert-sind.html)

Micha 15. Jan 2004 09:57


tree items zählen die rot markiert sind
 
Ich habe für einen Tree eine Suchfunktion gebastelt. (siehe Code unten)

In ein Edit gibt man den Suchbegriff ein, mit einem Button-Click werden dann die Items rot markiert, die den Such-Begriff enthalten.

Nun möchte ich noch die Anzahl der Items ausgeben, die gefunden wurden.
Kann mir bitte wer weiterhelfen?

Delphi-Quellcode:
procedure TForm1.treeCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
 i : integer;
  begin
// LowerCase = Umwandlung in Kleinbuchstaben.
   if Pos(LowerCase(edt_suchen.text),LowerCase(node.text))>0 then
   begin
     tree.Canvas.Font.Color := clred;
     ShowMessage(inttostr(tree.Items.Count)); //Gibt die Anzahl aller Datensätze aus
   end;
end;

gothic_mike 16. Jan 2004 01:32

Re: tree items zählen die rot markiert sind
 
Hallo,

Zitat:

Zitat von Micha
Delphi-Quellcode:
procedure TForm1.treeCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
 i : integer;
  begin
// LowerCase = Umwandlung in Kleinbuchstaben.
   if Pos(LowerCase(edt_suchen.text),LowerCase(node.text))>0 then
   begin
     tree.Canvas.Font.Color := clred;
     ShowMessage(inttostr(tree.Items.Count)); //Gibt die Anzahl aller Datensätze aus
   end;
end;

hmm, nimm eine globale variable, setze sie zu begin der suche auf 0 und erhöhe sie jedesmal um eins, wenn ein eintrag rot markiert wird und zum schluss hast du die anzahl der gefundenen einträge...

Delphi-Quellcode:
// ...
  public
    gefunden: Integer;
// ...
  begin
    tree.Canvas.Font.Color := clRed;
    inc(gefunden);
// ...
bye4now, gothic_mike

Micha 16. Jan 2004 07:12

Re: tree items zählen die rot markiert sind
 
Klappt super.

Danke.

Micha 16. Jan 2004 11:25

Re: tree items zählen die rot markiert sind
 
Klappt leider doch noch nicht so.

Es werden immer rot gefärbte Items dazugezählt, die gerade sichtbar sind.
D. h., wenn ich runterscrolle zählt er wieder welche dazu, wenn ich raufscrolle ...

Muss man vielleicht noch irgendwie sagen, dass er dann stoppen soll?

choose 16. Jan 2004 12:17

Re: tree items zählen die rot markiert sind
 
Hallo Micha,

mit dem von gothic_mike vorgeschlagenen Ansatz, zählst Du faktisch die "Anzahl vorgenommenen Rotfärbungen beim Zeichnen". Dieser Ansatz ist in sofern kritisch, als dass Du nicht sicherstellen kannst, dass wirklich jeder Knoten gezeichnet wird (außerhalb des ClientRects des Trees, Invisible, minimierter Zweig, etc) und Du keine unmittelbare Einflussmöglichkeit auf das Eintreten des Zeitpunkts des zeichnen kannst, so dass auch ein Einsatz der Form
Delphi-Quellcode:
Self.FGefunden:= 0;
Self.EdtSuchen.Text:= SomeValue;
ShowMessage(IntToStr(Self.FGefunden));
keine brauchbare Lösung bietet.

Du wirst nicht um ein Traversieren (alle Knoten einer Struktur durchlaufen) herum kommen und jeden Knoten erneut gegen das Kriterium prüfen müssen. Leider kenne ich zu diesem Zweck keine vorgefertigte Methode, die mit einer CallBack-Funktion aufgerufen werden kann und das Missbrauchen von CustomSort halte ich ebenfalls für kritisch.

Aus diesem Grund biete ich Dir an dieser Stelle eine entsprechene Traversierungsmethode für Deinen Spezialfall an. Zunächst führe ich hierzu die private Methode DoesNodeMatchCriteria ein, die genau dann True zurückgibt, wenn ein Knoten das von Dir beschriebene Kriterium erfüllt:
Delphi-Quellcode:
function TForm1.DoesNodeMachCriteria(const ANode: TTreeNode): Boolean;
begin
  Result:= AnsiStartsText(Self.EdtSuchen.Text, ANode.Text);
end;
so dass zunächst Deine Zeichenroutine vereinfacht werden kann:
Delphi-Quellcode:
procedure TForm1.treeCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if DoesNodeMatchCriteria(Node) then
    Sender.Canvas.Font.Color:= clRed;
end;
anschließend führe ich die tatsächliche Zählmethode CountMatchingNodes ein:
Delphi-Quellcode:
function TForm1.CountMatchingNodes: Cardinal;
  procedure TraverseNodes(const ANode: TTreeNode; var ASum: Cardinal);
  var
    myNode: TTreeNode;
  begin
    myNode:= ANode;
    // iterate every node at this level
    while Assigned(myNode) do
    begin
      if DoesNodeMatchCriteria(myNode) then
        Inc(ASum);

      // traverse recursive
      TraverseNode(myNode.getFirstChild, ASum);

      myNode:= myNode.getNextSibling;
    end;
  end;

begin
  Result:= 0;
  TraverseNodes(TreeView1.Items.GetFirstNode, Result);
end;
Sie basiert im Wesentlichen auf der Unterprozedur TraverseNodes, die für alle Knoten auf derselben Ebene wie dem übergebenen Knoten überprüft, ob sie dem Kriterium entsprechen und einen als Referenz übergebenen Zähler um diese Anzahl erhöht
Delphi-Quellcode:
myNode:= ANode;
while Assigned(myNode) do
begin
  if DoesNodeMatchCriteria(myNode) then
    Inc(ASum);
  myNode:= myNode.getNextSibling;
end;
weil die Unteroutine mit dem Wurzelelement des Treeviews aufgerufen wird und der als Referenz übergebene Wert dem Wert Result von CountMatchingNodes entspricht, zählt dieser Teil der Lösung bereits alle "roten Knoten" auf der ersten Ebene.

Um nun auch alle Unterknoten der Knoten sowie deren Unterknoten usw zu überprüfen, wende ich eine Rekursion an. Die Unterprozedur TraverseNodes ruft "sich selbst" mit dem ersten Unterknoten der gerade betrachteten Knotens auf, so dass alle Unterknoten auf dieser Ebene überprüft werden. Weil die Routine für jeden Aufruf auf dieselbe Weise verfährt, werden letztlich alle Knoten durchlaufen und überprüft.


Um die Methode CountMatchingNodes nun zu verwenden, kannst Du zB folgendes Schreiben
Delphi-Quellcode:
Self.EdtSuchen.Text:= SomeValue;
ShowMessage(IntToStr(CountMatchingNodes));

Micha 17. Jan 2004 07:09

Re: tree items zählen die rot markiert sind
 
Wow, danke für deine Mühe.

Sieht nicht schlecht aus. Konnte es leider noch nicht ausprobieren.

Gibt es denn keine einfachere / kürzere Möglichkeit?

Neg 18. Jan 2004 17:10

Re: tree items zählen die rot markiert sind
 
Ist das denn nicht bereits eine kurze und einfache Variante? :gruebel:
Also, ich denke, noch kürzer und einfacher geht es wohl kaum noch... :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 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