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 Node eindeutig identifizieren, JvPageListTreeView (https://www.delphipraxis.net/126434-node-eindeutig-identifizieren-jvpagelisttreeview.html)

haentschman 24. Dez 2008 08:29


Node eindeutig identifizieren, JvPageListTreeView
 
Hallo alle...

...auch wenn es JvPageListTreeView ist ist es von CustomTreeView abgeleitet.

Prinzipielle Frage:

Problem:

- ich rufe auch aus anderen Fenstern die Einstellungen mit der entsprechenden Page auf.
- dazu muß ich den entsprechenden Eintrag der PageListTreeView auswählen. Dann wird die entsprechende Page aktiviert.
- über den Index des Items kann ich den Eintrag "select" ausführen.

nun zum Problem:
- wenn ich irgendwann einen Eintrag in der PageListTreeView hinzufüge sind sämtliche Indexe verändert, da ich den Tree alphabetisch sortiert haben möchte.
- d.h. daß im Quelltext der anderen Fenster die Zuordnungen nicht mehr stimmen. Da es sich um nicht gerade wenige Aufrufstellen im Programm handelt gefällt mir das gar nicht.
- rückwärts über Veränderung der Page verändert sich der Tree nicht mit :(

Zusammenfassung: der Index ist nicht eindeutig, die verlinkte Page schon.

Frage:
- wie kann ich den Node eindeutig identifizieren unabhängig von der Sortierung und dem Index

Danke für Infos... :hi:

Chemiker 24. Dez 2008 09:10

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Frohe Weihnachten Andreas,

ich arbeite zwar nicht mit den Komponenten wie Du, sondern setze ein einfacher TreeView ein. Ich habe es aber so gelöst, dass ich an jeder Node ein Object hänge.

Bis bald Chemiker

RWarnecke 24. Dez 2008 09:19

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Gehe doch einfach über die Eigenschaft Selected.

lbccaleb 24. Dez 2008 10:26

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hey, hab noch ne Demo von:

Hier

vllt kann die dir helfen!

(unten Angehängt)

haentschman 24. Dez 2008 12:38

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Danke für die Infos...

Zitat:

Gehe doch einfach über die Eigenschaft Selected.
...ich möchte aber einen bestimmten Node von "außerhalb" selektieren. Das geht einfach über den Index. Da aber bei Veränderungen des Tree´s der Index sich verändert würde ich das lieber anders identifizieren.

...die anderen Ideen arbeite ich mal durch.

PS: das mit dem Objekt anhängen verstehe ich nicht ganz :gruebel:


Frohe Weihnachten allen... :P

mkinzler 24. Dez 2008 12:39

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Versuch es mal mit der Eigenschaft .Tag

haentschman 24. Dez 2008 12:43

Re: Node eindeutig identifizieren, JvPageListTreeView
 
hatte ich auch schon im Sinn, aber nur der TreeView als gesamtes hat einen Tag. Die Nodes selbst haben keine Eigenschaften, welche ich mißbrauchen könnte.

Ich hatte schon so komische Ideen wie eine Image List mit leeren Images und jedem Node ein Image zuweisen und über den ImageIndex selektieren...fand ich aber zu sehr um die Ecke :roll:

Danke...

im Moment selektiere ich per Index:
Delphi-Quellcode:
JvPageListTreeView1.Items.Item[17].Selected:= True;
da hätten wir noch die Möglichkeit per
Delphi-Quellcode:
JvPageListTreeView1.Select( NODE );
...nur weiß ich nicht wie ich den NODE identifiziere z.B. per Text :gruebel:

PS: habe eben herausgefunden, daß meine o.g. komische Idee gar nicht realisierbar ist. :?

RWarnecke 24. Dez 2008 14:28

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Vielleicht hilft Dir ja diese Funktion weiter :
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;

omata 24. Dez 2008 14:47

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Warum exit und dann auch noch zweimal?

Delphi-Quellcode:
function TForm.TreeNodeSearch(aNode: TTreeNode; SearchItem: string): TTreeNode;
begin
  Result := nil;
  if (aNode.hasChildren) and (SearchItem <> '') then begin
    aNode:=aNode.GetFirstChild;
    while assigned(aNode) and not assigned(Result) do begin
      if SearchItem = aNode.Text then
        Result := aNode;
      aNode:=aNode.getNextSibling;
    end;
  end;
end;

RWarnecke 24. Dez 2008 14:51

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Deine Funktion macht aber igrgendwie nicht das was meine macht.

haentschman 24. Dez 2008 17:02

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Danke für Eure Antworten...

jedesmal bei Aufruf suchen... find ich nicht so prickelnd :( , obwohl das funktionieren würde.

Ich werde mal eine Procedure mit einer case Anweisung probieren welche mir dann auf den entsprechenden Index "umleitet". Bei Änderungen am Tree muß ich dann nur die eine case Anweisung ergänzen / ändern.

bis bald... :hi:

Namenloser 24. Dez 2008 17:22

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von haentschman
hatte ich auch schon im Sinn, aber nur der TreeView als gesamtes hat einen Tag. Die Nodes selbst haben keine Eigenschaften, welche ich mißbrauchen könnte.

Nutzt diese Komponente etwas anderes als ein TTreeNode für die Nodes? Jedes TTreeNode hat nämlich die Eigenschaft Data, die genau dafür da ist. Da kannst du auch problemlos ein Objekt direkt drin speichern, denn das ist ja eigentlich nichts anderes als ein Pointer.

omata 24. Dez 2008 18:11

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von RWarnecke
Deine Funktion macht aber igrgendwie nicht das was meine macht.

ja? Meine Tests ergaben genau das selbe Verhalten. Wo ist denn dort ein Unterschied in der Funktionalität?

RWarnecke 24. Dez 2008 18:22

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Aus der Online-Hilfe zu GetNextSibling:
Returns the next node in the tree view at the same level as the calling node.


Ich gehe Anhand der Anzahl der Einträge jeden Eintrag durch.

omata 24. Dez 2008 18:44

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von RWarnecke
Ich gehe Anhand der Anzahl der Einträge jeden Eintrag durch.

Nichts anderes macht getNextSibling, siehe dazu auch GetFirstChild.

haentschman 24. Dez 2008 19:16

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Ich habe das "Problemchen" zwar schon im Griff aber mich würde das trotzdem interressieren... :wink:
Zitat:

Jedes TTreeNode hat nämlich die Eigenschaft Data, die genau dafür da ist. Da kannst du auch problemlos ein Objekt direkt drin speichern
ein paar Fragen dazu:
:?: was für ein Objekt würdest du dort hinterlegen ?
:?: wie würdest du über das Objekt den entsprechenden Node per Quellcode selektieren ?

:hi:

Namenloser 24. Dez 2008 20:34

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von haentschman
ein paar Fragen dazu:
:?: was für ein Objekt würdest du dort hinterlegen ?

Das hängt natürlich davon ab, was für eine Struktur du auf dem Baum abbildest. Speicher das Objekt ab, das in der Struktur dem Knoten entspricht.

Zitat:

:?: wie würdest du über das Objekt den entsprechenden Node per Quellcode selektieren ?
Kommt darauf an, ob der Knoten nach der Umsortierung immer noch der gleiche ist, er also ncith zwischenzeitlich freigegeben wird o.ä. Wenn ja, würde ich einfach in dem Datenobjekt wiederum eine Referenz auf den Knoten abspeichern. Wenn nicht, bleibt wohl wirklich nichts anderes übrig, als den ganzen Baum per Schleife durchzugehen und den Knoten zu suchen.

haentschman 24. Dez 2008 20:52

Re: Node eindeutig identifizieren, JvPageListTreeView
 
...nun ja, wenn ich mal viel Zeit habe. :P
...ich habe das nun so gelöst:
Delphi-Quellcode:
procedure TDMallgemein.AufrufEinstellungen(Seite: Integer);
var TempIndex: Integer;
begin
  case Seite of
    1: TempIndex:= 0; //Allgemein
    2: TempIndex:= 1; //Anlagenschema
    3: TempIndex:= 8; //Filterart
    4: TempIndex:= 9; //Filtergröße
    5: TempIndex:= 10; //Filterqualität
    6: TempIndex:= 2; //Anschlüsse
    7: TempIndex:= 3; //Bezeichnungen Technische Daten
    8: TempIndex:= 17; //Terminplaner
    9: TempIndex:= 7; //externe Formulare
    10: TempIndex:= 5; //Drucken
    11: TempIndex:= 18; //Vorlagen Tätigkeiten
    12: TempIndex:= 15; //Nummernkreise
    13: TempIndex:= 14; //Monteure
    14: TempIndex:= 13; //Lieferanten
    15: TempIndex:= 11; //Hersteller
    16: TempIndex:= 6; //Einheiten
    17: TempIndex:= 19; //Wartungsart
    18: TempIndex:= 16; //Serviceart
    19: TempIndex:= 12; //Kältemittel
    20: TempIndex:= 4; //Brandklassen
  end;
  FEinstellungen.JvPageListTreeView1.Items[TempIndex].Selected:= True;
end;
- die Seite bleibt gleich
- nach Hinzufügen einer Einstellung per Quellcode (grundsätzlich manuell) brauche ich nur einmal den TempIndex anzupassen, da alle Aufrufe die Seite wählen.
- eigentlich eine einfache Lösung. Zwar nicht ganz automatisch, aber ich habe die Änderungen nur an einer Stelle und nicht quer Beet durch die Unit´s.

Trotzdem Danke und noch einen schönen Tag... :P

alzaimar 24. Dez 2008 21:00

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Du hast also einen Baum, deren Knotenreihenfolge nicht eindeutig ist. Und du willst die Knoten irgendwie eindeutig identifizieren. Die 'Data'-Eigenschaft wurde schon genannt. Dort kommt eine eindeutige ID rein, die Du einmalig vergibst. Über die ID kannst Du den Knoten nun eindeutig identifizieren. Das man danach suchen muss, ist doch vollkommen egal, denn die paar Mikrosekunden merkt man eh nicht.

Wenn Dir das nicht passt, dann pflege eine zweite unsortierte Liste, in die die Knoten stehen. Der Index in dieser Liste (oder Array) ist dann deine ID. Wenn nun ein Knoten hinzukommt, wird dieser ans Ende der Liste gepackt und bekommt dadurch wieder eine eindeutige ID (Index in die Liste).

Zugriff über 'KnotenListe[IdxAllgemeineEinstellungen]'.

haentschman 24. Dez 2008 22:37

Re: Node eindeutig identifizieren, JvPageListTreeView
 
hmmm... irgendwie habe ich das Gefühl daß wir uns mißverstehen.
Zitat:

Die 'Data'-Eigenschaft wurde schon genannt. Dort kommt eine eindeutige ID rein, die Du einmalig vergibst.
...dümmlich ist nur, daß man an die Data Eigenschaft nur dran kommt, wenn man den Index des Knotens kennt.
Delphi-Quellcode:
JvPageListTreeView.Items.Item[Index].Data
- wenn ich mit der Maus oder mit der Tastatur durch den Tree navigiere habe ich zu jeder Zeit den NODE, dessen Index und andere Eigenschaften ( wie Data) verfügbar.
- da ich aber ohne Tastatur und Maus einen bestimmten Knoten selektieren muß und der Index "eigentlich" nicht bekannt bzw. durch die Sortierung nicht eindeutig ist suchte ich nach einer anderen Möglichkeit der Selektierung.

Mehrere Varianten kommen wie genannt in Frage:
- eine 2. Liste entsprechend mitführen
- meine Variante mit der case Anweisung
- jedesmal den gesamten Tree nach dem Text durchsuchen und den Node oder dessen Index auswerten.

Fazit:
- nach Text suchen fand ich auch zu unflexibel, wenn sich die Texte im Tree mal ändern sollten.
- die case Anweisung fand ich nach meiner Überlegung am einfachsten zu pflegen bzw. anzupassen, da die Änderungen an einer Stelle im Quelltext erfolgen.

...alle Klarheiten beseitigt ? :P

Danke für Eure Mithilfe.

:hi:

Namenloser 25. Dez 2008 00:01

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von haentschman
- nach Text suchen fand ich auch zu unflexibel, wenn sich die Texte im Tree mal ändern sollten.

Du kannst das aber flexibel halten, indem du nicht den Text vergleichst, sondern die Eigenschaft Data. Enwteder indem du ein Objekt darin speicherst (was für mich so immer am einfachsten war), oder eine eindeutige Nummer (was alzaimar meint).

haentschman 25. Dez 2008 08:24

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Guten Morgen...
Zitat:

Du kannst das aber flexibel halten, indem du nicht den Text vergleichst, sondern die Eigenschaft Data.
- auch eine Variante :thumb:

Danke an alle...

alzaimar 25. Dez 2008 09:51

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Zitat:

Zitat von haentschman
hmmm... irgendwie habe ich das Gefühl daß wir uns mißverstehen.

Nicht 'wir uns', sondern 'Du mich'.

Zitat:

Zitat von haentschman
...dümmlich ist nur, daß man an die Data Eigenschaft nur dran kommt, wenn man den Index des Knotens kennt.

Delphi-Quellcode:
Function IndexOfNode(aDataContents : Integer) : Integer;
Begin
  For Result:=0 to TreeView.Nodes.Count-1 do
    If Integer (TreeView.Nodes[Result].Data) = aDataContents Then
      Exit;
  Result := -1
End;
So bekommst Du dann den Index des Knotens. Also nix mit '...dümmlich..' :zwinker:
Du deklarierst deine ID als Konstanten, z.B.
Delphi-Quellcode:
Const
  IDDatenbankSeite = 0;
  IDBenutzereinstellungen = 1;
  ...
Dann fügst Du die Knoten in deinen Baum ein, wobei Du der 'Data'-Eigenschaft die ID-Konstanten zuweist.
Auf einen konkreten Knoten (z.B. den mit den Benutzereinstellungen) greifst Du dann so zu:
Delphi-Quellcode:
TreeView.Nodes[IndexOfNode(IDBenutzereinstellungen)].Selected := True
Wenn Dir das zu blöd ist, merkst Du Dir die Indizes der einzelnen ID-Konstanten. Allerdings musst Du die dann bei Änderungen an der Baumstruktur erneut zuweisen:
Delphi-Quellcode:
Var
  idxDatenbankseite,
  idxBenutzereinstellungen : Integer;
...
  idxDatenbankseite := IndexOfNode(IDDatenbankSeite);
  idxBenutzereinstellungen := IndexOfMode(IDBenutzereinstellungen);
...
  TreeView.Nodes[idxBenutzereinstellungen].Selected := True
Übrigens hätte ich als Anwender ein Riesenproblem damit, das sich die Reihenfolge des Baumes ändert, wenn neue Eigenschaftsseiten hinzukommen. Anwender bevorzugen kleiche *Positionen* von Dingen als wenn sie in einer sortierten Liste jedesmal suchen müssen. Du hättest in unterschiedlichen Sprachen auch ein unterschiedliches Layout. Toll für den, der deine Anwendung in beiden Sprachen bedienen muss.

Obige vorgeschlagene Trennung von Position und Identifikation bleibt jedoch hiervon unberührt, da es die klar robustere Implementierung ggü. fest verdrahteten Index-Konstanten ist.

haentschman 25. Dez 2008 10:34

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für Deine Zeit... 8)

...klar das Dein Code funktioniert :wink:
...aber das ganze ist viel simpler...siehe Bild

- ich benutze ein JvPageListTreeView in Verbindung mit JvPageList.
- jeder Knoten im Tree ist "verlinkt" mit einer Page aus der JvPageList (Designzeit)...(wie PageControl nur ohne Reiter)
- der Tree verändert sich wenn überhaupt nur zur Designzeit
- wenn der Tree auch zur Laufzeit Veränderungen hätte, müßte man selbstverständlich mehr Aufwand betreiben. :zwinker:
- der Tree ist einfach nur eine Liste und nicht kompliziert "verknotet"
- da sich der Tree eigentlich nicht verändert fand ich das Durchsuchen der Nodes jedesmal zur Laufzeit etwas übertrieben.
- mir ging es im wesentlichen um die Wartbarkeit des Codes bei Veränderungen / Ergänzungen des Tree´s

PS: mit dem "dümmlich" meinte ich den Direktzugriff auf die Eigenschaft. Mit einem Schleifendurchlauf durch alle Nodes ist klar, daß man den Index bzw. die Eigenschaften des Nodes auswerten kann. :zwinker:

Zitat:

Du hättest in unterschiedlichen Sprachen auch ein unterschiedliches Layout.
...ist korrekt, aber da die Software durch die implementierten Formulare und gesetzlichen Regelungen nur in Deutschland Verwendung findet und nur in Deutsch verfügbar ist, ist dieser Punkt eher zu vernachlässigen
Zitat:

Übrigens hätte ich als Anwender ein Riesenproblem damit, das sich die Reihenfolge des Baumes ändert, wenn neue Eigenschaftsseiten hinzukommen. Anwender bevorzugen kleiche *Positionen* von Dingen als wenn sie in einer sortierten Liste jedesmal suchen müssen.
:gruebel: ich glaube da streiten sich die Gelehrten. Mir persönlich ist die sortierte Liste lieber, da ich anhand dessen was ich suche nach "oben" oder "weiter runter" blättern muß.

Ich wünsche Dir frohe Feiertage... :hi:

:oops: verkehrtes Bild...

alzaimar 25. Dez 2008 11:40

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich kenne dieses Paradigma. Ich würde jedoch versuchen, die Eigenschaftsseiten zu gruppieren, also eine Art Hierarchie hereinzubringen. Dann wird das übersichtlicher.
Betrieb
-- Allgemeine Einstellungen
-- Programmstart
-- Datenbank
Filter
-- Filterarten
-- Filtergrößen
-- Filterqualitäten
...

Bei der Frage, was sich ein Anwender eher merkt, streiten sich die Gelehrten übrigens nicht: Positionen erkennen und merken kann sich der Mensch schon seit Jahrmillionen, Lesen erst seit ein paar hundert Jahren. Bei der Ergonomie sollten Instinkte berücksichtigt werden, kognitive Fähigkeiten eher nicht. Dann wird ein Dialog als 'einfach', 'übersichtlich' und 'nicht überladen' angesehen.

Wenn Du schon Paradigmenwechsel beim Eingabedialog (überladene Pagecontrol => strukturierte Treeview) durchführst, solltest Du konsequent sein, und ihn auch bis zum Ende durchziehen (und nicht auf halbem Wege stehenbleiben). Großartig übersichtlicher dein Dialog so ja auch nicht, denn Du stellst ja nur die Tabs anders dar.

Solche Eigenschaftsdialoge (ob nun hierarchisch oder nicht) habe ich auch zur Genüge implementiert. Ich verwende mittlerweile die von mir beschriebene Implementierung, da bei der Weiterentwicklung immer wieder neue Eigenschaftsseiten hinzukommen. Ich gruppiere auch um, sodaß sich die Indexe während der Entwicklung ständig ändern. Mit der Trennung habe ich nun keine Probleme mehr. Allerdings hänge ich in die Data-Eigenschaft das TabSheet in in dessen Tag-Eigenschaft meine ID. So kann ich beim Wechsel im Baum das entsprechende Tab anzeigen und finde gleichzeitig den richtigen Knoten zu einem Tab. Ich habe z.B. in meinen Datenbank-Dialogen grundsätzlich einen Knopf "Einstellungen". Wenn man den drückt, kommt der Eigenschaftsdialog hoch, wobei gleich die 'Datenbank'-Seite ausgewählt ist.

Zitat:

Zitat von haentschman
- wenn der Tree auch zur Laufzeit Veränderungen hätte, müßte man selbstverständlich mehr Aufwand betreiben. :zwinker:

Aus deinem anderen Thread
Zitat:

Zitat von haentschman
...einige Einstellungen dürfen nur verfügbar sein, wenn eine Datenbankverbindung besteht...

Ja, wat denn nu? Oder gehts nicht um diesen Dialog?

haentschman 25. Dez 2008 12:10

Re: Node eindeutig identifizieren, JvPageListTreeView
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Ich würde jedoch versuchen, die Eigenschaftsseiten zu gruppieren
...hast Recht...ich mach mich dann mal an die Arbeit :wink:

Zitat:

Ja, wat denn nu?
...ähmmm
- es gibt im Prinzip 2 Versionen des Tree´s (visuell) mit und ohne Datenbankverbindung
- es ist zwar nicht die feine englische Art aber um mir das Neuaufbauen des Tree´s zu ersparen habe ich die 2 Versionen des Tree´s übereinander gelegt und je nach Status ist der eine oder der andere Visible.

PS: an deinem Beispiel kann man deutlich sehen, daß die Icons im Tree das ganze optisch auch auflockern. :thumb:

...bis später.

[edit]
...ist´s so besser ? :wink:
...siehe Bild

PS:
- die 5 da oben ist der derzeitige AbsolutIndex des gewählten Knotens...Information für mich 8)
- die Breite ist so ok, da es Einstellungen gibt, welche die gesamte Breite beanspruchen. (Bild2)
[/edit]


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