![]() |
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; |
Re: tree items zählen die rot markiert sind
Hallo,
Zitat:
Delphi-Quellcode:
bye4now, gothic_mike
// ...
public gefunden: Integer; // ... begin tree.Canvas.Font.Color := clRed; inc(gefunden); // ... |
Re: tree items zählen die rot markiert sind
Klappt super.
Danke. |
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? |
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:
keine brauchbare Lösung bietet.
Self.FGefunden:= 0;
Self.EdtSuchen.Text:= SomeValue; ShowMessage(IntToStr(Self.FGefunden)); 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:
so dass zunächst Deine Zeichenroutine vereinfacht werden kann:
function TForm1.DoesNodeMachCriteria(const ANode: TTreeNode): Boolean;
begin Result:= AnsiStartsText(Self.EdtSuchen.Text, ANode.Text); end;
Delphi-Quellcode:
anschließend führe ich die tatsächliche Zählmethode CountMatchingNodes ein:
procedure TForm1.treeCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); begin if DoesNodeMatchCriteria(Node) then Sender.Canvas.Font.Color:= clRed; end;
Delphi-Quellcode:
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
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;
Delphi-Quellcode:
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.
myNode:= ANode;
while Assigned(myNode) do begin if DoesNodeMatchCriteria(myNode) then Inc(ASum); myNode:= myNode.getNextSibling; end; 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)); |
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? |
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 04:54 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-2025 by Thomas Breitkreuz