Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Probleme mit der TreeView-Komponente...
Terra23 - Mo 25.06.12 20:03
Titel: Probleme mit der TreeView-Komponente...
Hi Leute!
Ich habe folgendes Problem:
In meinem Programm befülle ich ein TreeView, indem ich in ein Edit-Feld einen Text eingebe und mit Enter bestätige.
Es findet dann eine Abfrage statt, ob der Eintrag schon vorhanden ist.
Problem: Nur, wenn die Treeview-Knoten alle eingeklappt sind ODER ich mich im richtigen Knoten befinde, wird ein doppelter Eintrag erkannt. Ansonsten nicht. Ich veranschauliche das mal kurz...
Punkt 1
--A
--B
--C
--D
Punkt 2
--E
--F
--G
Punkt 3
--H
--I
--J
Ich will nun ein "A" hinzufügen. Befinde ich mich in "Punkt 1", erkennt er, dass der Eintrag schon existiert. Befinde ich mich bei "Punkt 2" oder "Punkt 3", dann erkennt er dies nicht und lässt mich das "A" hinzufügen.
Hier mal mein Code für euch (sorry, wenn er nicht sehr elegant aussieht):
Delphi-Quelltext
1: 2: 3:
| If (Key=Char(VK_RETURN)) And (Edit1.Text<>'') Then If NOT (NodeExists(Edit1.Text, NIL)) Then Setliste.Items.AddChild(GetTreeItems(Setliste.Items, Art), Edit1.Text); |
Art ist eine String-Variable und enthält den Knotennamen in den der Eintrag wandern soll (also "Punkt 1", "Punkt 2" oder "Punkt 3"). Setliste ist der Name meiner TreeView.
Ich habe das auch nur per Zufall bemerkt und weiß mir da echt keinen Rat.
Ich hoffe auf eure Hilfe.
Gruß,
Lex
Mathematiker - Mo 25.06.12 21:33
Hallo Terra 23,
ich kenne diesen Effekt vom Suchen nach Einträgen mit bestimmten Textteilen in einem Treeview.
Im Netz habe ich vor längerer Zeit als Ersatzmethode gefunden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| function NodeExists(Parent : TTreeNode; Text : String) : TTreeNode; var i: Integer; begin Result := nil; for i := 0 to Tree.Items.Count - 1 do begin if (Parent <> nil) xor ((Parent = nil) and (Tree.Items.Level = 0)) then begin if (UpperCase(Tree.Items.Text) = UpperCase(Text)) then begin if (Parent = nil) xor ((Parent <> nil) and (Parent = Tree.Items.Parent)) then begin Result := Tree.Items; Break; end; end; end; end; end; |
Für meine Zwecke war es geeignet. Allerdings arbeite ich mit Delphi 5. Vielleicht hilft es Dir ja auch.
Beste Grüße
Mathematiker
Terra23 - Mo 25.06.12 21:43
Danke, das werde ich mal ausprobieren. Muss es in der Zeile wirklich "Xor" heißen?
Gruß,
Terra
Terra23 - Mo 25.06.12 22:22
Funktioniert irgendwie nicht ... er kennt den Bezeichner "Tree" nicht. Habe die Einträge schon in den Namen des Items (TreeView1) geändert, aber das kennt er auch nicht... :(
Mathematiker - Mo 25.06.12 22:54
Terra23 hat folgendes geschrieben : |
| Funktioniert irgendwie nicht ... er kennt den Bezeichner "Tree" nicht. Habe die Einträge schon in den Namen des Items (TreeView1) geändert, aber das kennt er auch nicht... :( |
Tut mir leid. Tree ist bei mir der Name des Treeview.
Leider kann ich Dir nicht viel weiterhelfen. So richtig verstehte ich die Treeview-Komponente leider auch nicht.
Beste Grüße
Mathematiker
jaenicke - Di 26.06.12 06:25
Das sieht nach dem typischen Problem aus, wenn man die Daten in einer visuellen Komponente vorhält. Eigentlich müsste es genau umgekehrt sein: Die Daten liegen irgendwo und werden in der TreeView nur angezeigt.
Dann kannst du in den Daten suchen und die TreeView danach nur aktualisieren.
Oder du nimmst die VirtualTreeView und hängst an die einzelnen Datensätze gleich nur Pointer auf die Daten.
Was deinen Code angeht:
Da fehlt irgendwie die Implementierung von NodeExists, denn das gibt es so als einzelne Funktion ja nicht standardmäßig. Ich schätze mal die Funktion geht vom aktuellen Knoten aus und findet den deshalb nicht.
Narses - Di 26.06.12 07:50
Moin!
Terra23 hat folgendes geschrieben : |
| Es findet dann eine Abfrage statt, ob der Eintrag schon vorhanden ist. |
Ich nehme einfach mal an, du willst wissen, ob sich ein Node mit einem bestimmten Text irgendwo im Treeview befindet. Die Position ist dir eigentlich egal, du willst nur keine doppelten Namen in den Nodes haben, richtig? Dann sollte es das hier bereits tun:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function IndexOfNode(ATreeView: TTreeView; AText: String): Integer; begin for Result := 0 to ATreeView.Items.Count -1 do if (UpperCase(ATreeView.Items.Item[Result].Text) = UpperCase(AText)) then Exit; Result := -1; end;
procedure TForm1.Button1Click(Sender: TObject); begin if (IndexOfNode(TreeView1, Edit1.Text) >= 0) then ShowMessage('gefunden') else ShowMessage('nicht drin'); |
Probier das mal aus. ;)
Mathematiker hat folgendes geschrieben : |
| Im Netz habe ich vor längerer Zeit als Ersatzmethode gefunden: |
Wo auch immer du diese Funktion her hast, die kann nicht korrekt sein, da fehlen Referenzen. z.B. ein .Item[i] bei den ganzen .Levels, nur als ein Beispiel. Ich halte diese Funktion für defekt. :nixweiss: (und glaube schlicht nicht, dass du sie so eingesetzt hast, ich kann sie mit D7 zumindest nicht mal compilieren, ohne die fehlenden Referenzen anzupassen, ganz zu schweigen von einer Tree-Referenz)
jaenicke hat folgendes geschrieben : |
| Oder du nimmst die VirtualTreeView und hängst an die einzelnen Datensätze gleich nur Pointer auf die Daten. |
Ich hätte schwören können, dass du das schreiben wirst... 8) Warum handelst du mit denen eigentlich keine Provision aus? :idea: Das sollte sich echt lohnen, für dich... :zwinker:
cu
Narses
Terra23 - Do 28.06.12 19:12
@Narses: Vielen Dank, mit dem Code hat es funktioniert. Und du hast auch meine Frage richtig verstanden. ;)
Das kann nicht jeder..
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!