Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Doppelte Einträge in einem Treeview verhindern (https://www.delphipraxis.net/135435-doppelte-eintraege-einem-treeview-verhindern.html)

RWarnecke 10. Jun 2009 18:51


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:
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;
Die Funktion "TreeNodeSearch" macht folgendes :
Delphi-Quellcode:
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;
Die Edit-Funktion klappt leider nicht. Es gibt aber auch keine Fehlermeldung. Wie kann ich diese Edit-Funktion realisieren ?

Satty67 10. Jun 2009 19:06

Re: Doppelte Einträge in einem Treeview verhindern
 
Also bei idYes soll der Name gesetzt werden, der vorm umbenennen war?
Delphi-Quellcode:
     
idYes: S := Node.Text; // Setzt wieder alten Wert vorm umbenennen
idNo: S := S + ' [new]';
Node.Text hält noch den alten Namen, der Node steht ja erst kurz davor unbenannt zu werden...

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;

RWarnecke 10. Jun 2009 19:46

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 ?

Satty67 10. Jun 2009 19:58

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.

RWarnecke 10. Jun 2009 20:52

Re: Doppelte Einträge in einem Treeview verhindern
 
Zitat:

Zitat von Satty67
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.

Ok, danke. Aber erst muss ich es hinbekommen mit der Änderung.

Zitat:

Zitat von Satty67
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?

Aber das müsste doch schon der Aufruf node.editedtext erledigen oder ?

Satty67 10. Jun 2009 21:01

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.

RWarnecke 11. Jun 2009 10:49

Re: Doppelte Einträge in einem Treeview verhindern
 
Zitat:

Zitat von Satty67
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.

Das Ereignis OnEdited wird doch nach dem Editeren aufgerufen. Ich habe jetzt mal folgendes probiert :
Delphi-Quellcode:
  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;
Nur das funktioniert nicht. Ich habe vermutlich das mit der Message falsch gemacht, weiß aber nicht genau wo und wie.

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.

Chemiker 11. Jun 2009 11:13

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:
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;
Bis bald Chemiker

DeddyH 11. Jun 2009 11:16

Re: Doppelte Einträge in einem Treeview verhindern
 
Wäre es so nicht performanter?
Delphi-Quellcode:
while (sNode <> NIL) and not Result do
Wenn das Ergebnis feststeht, muss man ja nicht weiterprüfen, oder hab ich die Routine falsch verstanden?

RWarnecke 11. Jun 2009 11:19

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:44 Uhr.
Seite 1 von 2  1 2      

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