![]() |
Doppelte Einträge in einem Treeview verhindern
Hallo zusammen,
ich stehe vor dem Problem, dass ich in einem Zweig von einem TreeView doppelte Einträge verhindern möchte. Dazu habe ich den folgenden Versuch angestellt mit dem Ereignis OnEdited :
Delphi-Quellcode:
Die Funktion "TreeNodeSearch" macht folgendes :
procedure TMainForm.TV_CategoryEdited(Sender: TObject; Node: TTreeNode;
var S: string); begin // To search for a duplicated tree node if TreeNodeSearch(Node.Parent, S) <> nil then begin case MessageBox(0, 'Sie haben einen doppelten Eintrag erstellt. Ändern ?', 'Doppelter Eintrag', MB_ICONQUESTION or MB_YESNO) of idYes: Node.EditedTex; idNo: S := S + ' [new]'; end; end; end;
Delphi-Quellcode:
Die Edit-Funktion klappt leider nicht. Es gibt aber auch keine Fehlermeldung. Wie kann ich diese Edit-Funktion realisieren ?
function TMainForm.TreeNodeSearch(aNode: TTreeNode; SearchItem: string): TTreeNode;
var I: Integer; begin result := nil; if (aNode = nil) or (SearchItem = '') then Exit; for I := 0 to aNode.Count - 1 do begin if SearchItem = aNode.Item[i].Text then begin Result := aNode.Item[i]; exit; end; end; end; |
Re: Doppelte Einträge in einem Treeview verhindern
Also bei idYes soll der Name gesetzt werden, der vorm umbenennen war?
Delphi-Quellcode:
Node.Text hält noch den alten Namen, der Node steht ja erst kurz davor unbenannt zu werden...idYes: S := Node.Text; // Setzt wieder alten Wert vorm umbenennen idNo: S := S + ' [new]'; btw: statt [new] würde sich [1]..[n] anbieten Vielleicht kannst Du was mit anfangen, ansonsten einfach ignorieren (der Teil für einen Zweig ist alleine ja recht übersichtlich)
Delphi-Quellcode:
function GetUniqueNodeText(aTreeView: TTreeView; aParentNode: TTreeNode;
aNodeText : String; OnlyInTwig : Boolean = True): String; var i : Integer; sl : TStringList; begin Result := aNodeText; {<--- Prüft nur einen Zweig bzw. erste Ebene --->} if OnlyInTwig then begin i := 0; while NodeTextExistsInTwig(aTreeView, aParentNode, Result) do begin inc(i); Result := aNodeText+'['+IntToStr(i)+']'; end; {<--- Prüft alle Nodes --->} end else begin sl := TStringList.Create; try // Namen sammeln, damit Items nicht x-mal durchlaufen werden muss // Aufwand relativiert sich bei großen Bäumen for i := 0 to aTreeView.Items.Count-1 do if Pos(AnsiUpperCase(aNodeText), AnsiUpperCase(aTreeView.Items[i].text)) > 0 then sl.Add(AnsiUpperCase(aTreeView.Items[i].text)); // Prüfen und gg. erweitern i := 0; while sl.IndexOf(AnsiUpperCase(Result)) >= 0 do begin inc(i); Result := aNodeText+'['+IntToStr(i)+']'; end; finally sl.Free; end; end; end; |
Re: Doppelte Einträge in einem Treeview verhindern
Hallo Satty67,
danke erstmal für Deine Antwort. Nur leider funktioniert es nicht. Die Funktion "GetUniqueNodeText" die Du gepostet hast, verstehe ich, aber weiss nicht, wie Sie bei meinem Problem weiterhelfen kann. Ich beschreibe nochmal, was ich machen möchte : Ich gebe den Befehl eine neue Node anzulegen. Der TreeView geht in den Editiermodus und es kann der Name eingegeben werden. Nachdem mit der Enter-Taste bestätigt wird, soll überpüft werden, ob die eingegebene Node in dem Zweig schonmal existiert. Dieses mache ich in dem Ereignis OnEditing durch die IF-Abfrage. Dann soll der User entscheiden über die Case-Anweisung ob der neue Namen geändert werden soll oder nicht. Entscheidet er sich für die Änderung, soll die Node wieder in den Editiermodus versetzt werden. Bei einem "Nein" soll an den bestehenden Namen nur ein "[new]" angehängt werden. Das mit der Verneinung funktioniert, nur leider mit dem Editiermodus nicht. Muss ich diese Abfrage in ein anderes Ereignis setzen oder habe ich einen Denkfehler in meiner Version ? |
Re: Doppelte Einträge in einem Treeview verhindern
ah OK, Du willst bei idYes zurück in den Editiermodus. Das hatte ich dann falsch verstanden.
Denke beim Ereignis Edited ist der Node noch in der Methode zum ändern des Nodes, weshalb aus dem Ereignis heraus ein erneuter Aufruf scheitert? €: Vielleicht TVN_BEGINLABELEDIT mit Post-Message bei idYes an den TreeView abschicken, hängt sich ja dann an und ruft den Edit-Modus gleich wieder auf? PS: function GetUniqueNodeText war als Ersatz für simples anhängen von [new] gedacht. Es kann ja sonst der Fall eintreten, das Du Einträge [new][new] anlegst, falls der Benutzer ständig den gleichen Namen eintippen will. |
Re: Doppelte Einträge in einem Treeview verhindern
Zitat:
Zitat:
|
Re: Doppelte Einträge in einem Treeview verhindern
EditText ruft TreeView_EditLabel (COM-Interface) auf, wenn sich der Node aber wie im aktuellen Fall noch im Editiermodus befindet, passiert nichts (vermute ich jetzt mal).
Es wird mit EditText ja keine Botschaft verschickt, sondern eine Funktion aufgerufen, die den Inplace-Editor aktiviert bzw. aktiviert lässt, wenn er schon aktiv ist. |
Re: Doppelte Einträge in einem Treeview verhindern
Zitat:
Delphi-Quellcode:
Nur das funktioniert nicht. Ich habe vermutlich das mit der Message falsch gemacht, weiß aber nicht genau wo und wie.
if TreeNodeSearch(Node.Parent, S) <> nil then
begin case MessageBox(0, PChar(rsDuplicateEntry), PChar(rsDuplicateEntryTitle), MB_ICONQUESTION or MB_YESNO) of idYes: begin PostMessage(Self.Handle, WM_NOTIFY, TVN_BEGINLABELEDIT, 0); Node.Text := S; end; idNo: S := S + ' [new]'; end; end; Dazu habe ich noch getestet, wenn ich in der Case-Anweisung bin, liefert mir TV_Category.IsEditing gleich False zurück. Edit : Die Delphi-Tags korrigiert. |
Re: Doppelte Einträge in einem Treeview verhindern
Hallo RWarnecke,
mir ist jetzt nicht ganz klar was Dein Problem ist, aber mit dieser Funktion kann man feststellen, ob man doppelte Einträge im TreeView vorhanden sind.
Delphi-Quellcode:
Bis bald Chemiker
function IstDoppelt(Nod: TTreeNodes; StrKnoten: String):boolean;
var sNode: TTreeNode; begin Result:= FALSE; // Eintrag noch nicht vorhanden. sNode:= nod.getFirstNode; while sNode <> NIL do // Solange prüfen bis kein Eintrag begin If (CompareText(sNode.Text, StrKnoten)=0) then // Ist der Knoten schon begin // vorhanden? Result:= TRUE; // Eintrag vorhanden end; sNode:= sNode.GetNext; // nächster Knoten prüfen end; end; |
Re: Doppelte Einträge in einem Treeview verhindern
Wäre es so nicht performanter?
Delphi-Quellcode:
Wenn das Ergebnis feststeht, muss man ja nicht weiterprüfen, oder hab ich die Routine falsch verstanden?
while (sNode <> NIL) and not Result do
|
Re: Doppelte Einträge in einem Treeview verhindern
Hallo Chemiker,
die doppelten Nodes zu finden ist kein Problem. Schaue nochmals in die Beschreibung von Beitrag #3. Dort habe ich alles genau beschrieben. |
Re: Doppelte Einträge in einem Treeview verhindern
Hallo DeddyH,
stimmt. Bis bald Chemiker |
Re: Doppelte Einträge in einem Treeview verhindern
Hallo,
mit dem Problem hab ich auch schon mal gekämpft. :wall: Zitat:
:arrow: In OnEdit prüfen ob der Nodetext schon vorhanden ist, wenn ja mit Postmessage eine selbst definierte Message abschicken. Dadurch kommst Du raus aus dem Ereignis, in dem die Aktivierung des Edit-Modus scheitert. In der Procedur dann die Problembehandlung durchführen. Hab Dir eine Beispiel-Unit zusammengestellt:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls; type TForm1 = class(TForm) TreeView1: TTreeView; procedure TreeView1Edited(Sender: TObject; Node: TTreeNode; var S: String); private { Private-Deklarationen } public { Public-Deklarationen } FDupeNodeText : String; function TreeNodeSearch(aNode: TTreeNode; SearchItem: string): TTreeNode; procedure PM_TVNodeTextAlreadyExists(var Msg: TMessage); message WM_USER +1001; end; var Form1: TForm1; implementation {$R *.DFM} function TForm1.TreeNodeSearch(aNode: TTreeNode; SearchItem: string): TTreeNode; var I: Integer; begin result := nil; if (aNode = nil) or (SearchItem = '') then Exit; for I := 0 to aNode.Count - 1 do begin if SearchItem = aNode.Item[i].Text then begin Result := aNode.Item[i]; exit; end; end; end; procedure TForm1.PM_TVNodeTextAlreadyExists(var Msg: TMessage); begin case MessageBox(0, 'Sie haben einen doppelten Eintrag erstellt. Ändern ?', 'Doppelter Eintrag', MB_ICONQUESTION or MB_YESNO) of idYes: TTreeNode( Msg.WParam ).EditText; idNo: TTreeNode( Msg.WParam ).Text := FDupeNodeText + ' [new]'; end; end; procedure TForm1.TreeView1Edited(Sender: TObject; Node: TTreeNode; var S: String); begin if TreeNodeSearch(Node.Parent, S) <> nil then begin // neue Caption speichern FDupeNodeText := S; // zurücksetzen S := Node.Text; // nach dem Ereignis Problem behandeln PostMessage(Handle, WM_USER +1001, integer(Node), 0); end; end; end. |
Re: Doppelte Einträge in einem Treeview verhindern
Hallo Lannes,
ich habe mal Dein Beispiel ausprobiert und es funktioniert wunderbar. Genau so habe ich es mir vorgestellt. Danke Dir nochmals. Ich werde mir das Beispiel jetzt näher zur Gemüte führen und es in mein bestehendes Programm einbauen. Danke auch nochmal an die anderen Helfer. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:56 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