Entwickler-Ecke

WinForms - TreeView Select Node Event


chip777 - Di 27.04.10 08:52
Titel: TreeView Select Node Event
Hi,

mein TreeView steht und ich möchte nun damit arbeiten. Und zwar würde ich gerne Informationen zur jeweils ausgewählten Node erhalten. Dafür muss ich aber wissen wie das mit dem Selected Event funktioniert. Immer wenn eine Node selektiert wird soll meine Methode aufgerufen werden, welche die Infos anzeigt.

Martin


ene - Di 27.04.10 09:27

Moin,

Nimm das AfterSelect und mittels e.Node.Text bekommst du den Wert des ausgewählten Nodes.


danielf - Di 27.04.10 10:01

Du musst einen Eventhandler auf das jeweilige Event (ene schlägt AfterSelect vor) setzen. Das kannst du entweder im Designer bei den Control-Properties (Reiter Event) oder im Code durch <treeView>.AfterSelect += new TreeViewEventHandler(tv_AfterSelect);.


chip777 - Di 27.04.10 11:16

Danke für die Infos, hat super geklappt.
Aber jetzt hab ich gleich noch ne Frage in diese Richtung:

Ich ändere jetzt ein Node und lade danach den TreeView neu. Ich habe die das Tag der Node gespeichert und kann so darauf zugreifen. Wie bekomme ich es hin, nachdem ich den TreeView neugeladen haben, die alte Ansicht wieder hergestellt wird?

Also ich will quasi im Programm eine Node selektieren, die einen bestimmten Tag Wert hat, diesen hab ich in einer Variablen namens ID gespeichert. Ich hoffe ich konnte mich verständlich ausdrücken.

Martin


danielf - Di 27.04.10 11:23

Du kannst das ausgewählte/markierte TreeNode über das TreeView Property SelectedNode auslesen und setzen.

Das hättest du aber mit einen Blick auf deine Intellisense oder auf MSDN selbst erahnen können. Bitte verwende diese Hilfestellung und stürzt dich nicht gleich auf das Forum, wo wir dir dann die Properties/Events vorlese.

Des Weiteren gilt dies [http://lmgtfy.com/?q=markiertes+node+setzen+treeview+.net+c%23].


chip777 - Di 27.04.10 12:28

Ich glaub ich habs jetzt.


chip777 - Di 27.04.10 13:58

user profile iconchip777 hat folgendes geschrieben Zum zitierten Posting springen:
Ich glaub ich habs jetzt.


Zumindest fast^^


C#-Quelltext
1:
2:
3:
4:
treeView1.Nodes.Clear();  //löscht den Bauminhalt
ErstellenBaumdiagramm();  //Erstellt ihn neu
treeView1.ExpandAll();  //Zeigt alle Knoten
treeView1.Select();  //Legt den Fokus auf den TreeView


Der Code passt momentan soweit, allerdings wollte ich jetzt den Fokus auf ein bestimmten Knoten legen, wie lautet dieser Befehl? mit treeView1.Select() wird der Fokus einfach auf den Knoten gelegt der gerade oben links im Bild zu sehen ist.
Ich hab schon mit Select() und TopNode rumprobiert, aber im Moment noch etwas erfolglos.


danielf - Di 27.04.10 14:03

:(

Siehe
user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst das ausgewählte/markierte TreeNode über das TreeView Property SelectedNode auslesen und setzen.


chip777 - Di 27.04.10 14:26

Bis jetzt hatte ich das Problem das ich nicht wusste wie ich die treeView1.SelectedNode speicher, jetzt hab ich es über var gemacht, siehe hier:

C#-Quelltext
1:
2:
3:
4:
var node = treeView1.SelectedNode;
...
treeView1.Focus();
treeView1.SelectedNode = node;


Trotzdem klappt es noch nicht.


danielf - Di 27.04.10 14:37

Hmm.. okay. ich weiß woran das Problem liegt. Der TreeNode ist nicht mehr mit dem neuen TreeView verbunden.

Wenn du die Struktur neu aufbaust, woran erkennst du, welcher Node vorher der selektierte war?

Ich vermute du musst es über ein Tag-Wert referenzieren. Sprich bei ErstellenBaumdiagramm:

C#-Quelltext
1:
2:
3:
TreeNode node = new TreeNode("blub");
node.Tag = REFERENZ;
treeView.Nodes.Add(node);


und dir nachher vor dem löschen das OBjekt holen/merken und nach dem neuaufbau suchen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
object referenz = treeView.SelectedNode.Tag;
treeView1.Nodes.Clear();
ErstellenBaumdiagramm();
treeView1.ExpandAll();

// ggf. rekursiv
foreach(TreeNode node in treeView1.Nodes)
{
    if (ReferencesEquals(node.Tag, referenz))
    {
       treeView1.SelectedNode = node;
    }
}


chip777 - Di 27.04.10 14:51

Super, das war genau das was ich gemeint habe.
Allerdings kommt bei Zeile 9 deines Codes ein Fehler:
Der Name "ReferencesEquals" ist im aktuellen Kontext nicht vorhanden.

Edit:
So lege ich meine Nodes an:

C#-Quelltext
1:
2:
3:
TreeNode VorNode = new TreeNode(Convert.ToString(dataGridView2[7, j].Value));
                            VorNode.Tag = Convert.ToString(dataGridView2[6, j].Value);
                            RobNode.Nodes.Add(VorNode);

Dadurch haben die im Tag schon eine eindeutige ID.

Deine Schleife hab ich so verändert:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
treeView1.Nodes.Clear();
                    ErstellenBaumdiagramm();
                    treeView1.ExpandAll();
                    treeView1.Focus();
                    foreach (TreeNode node in treeView1.Nodes)
                    {
                        if ((int)node.Tag == Id)
                        {
                            treeView1.SelectedNode = node;
                        }
                    }

Das funktioniert aber leider noch nicht. -.-

Btw. nicht über das Convert.ToString meckern, wenn ich das durch (string) ersetze kommt zwar kein CompilierFehler, aber während der Laufzeit kommt es zu Fehlern.


Kha - Di 27.04.10 14:58

Daniel meinte wahrscheinlich object.ReferenceEquals, aber hier sollte es auch ein einfacher Vergleich mit == tun.

PS: Musst du wirklich alle Knoten neu erstellen, kannst du die alten nicht beibehalten?


chip777 - Di 27.04.10 15:02

Kha ich glaub du hast Recht -.-
Keine Ahnung wieso ich es so kompliziert machen will, mein Problem war das ich wenn ich die Daten aktualisiere diese nicht einzeln ins TreeView bekomme, deshalb habe ich das alte gelöscht und ein neues erstellt. Falls es aber eine Möglichkeit gibt die alten Daten einfach zu ersetzen wäre das mit Sicherheit einfacher.

Sry, dass ich da nicht drauf gekommen bin, ich werd mal schauen ob ich es hinbekomme mit Aktualisieren.


chip777 - Di 27.04.10 15:14

Ok, ich kann das ganze wesentlich einfacher lösen. Ohne löschen und neu erstellen.
Sry nochmal das ich da nicht selbst draufgekommen bin.

Jetzt hab ich nur noch ein sehr kleines Problem dabei:
Ich nutze einen Knopf um das TreeView Item zu bearbeiten, dabei bekommt der Knopf den Fokus.
Wenn ich dann diese Zeilen ausführe funktioniert das natürlich nicht:

C#-Quelltext
1:
2:
treeView1.SelectedNode.Name = textBoxName.Text;
treeView1.SelectedNode.Name = textBoxVorgang.Text;

Hmmm....ich glaub ich speicher einfach die Stelle an der sich die selected Node befindet und danach schreib ich da wieder hin, mal schauen ob es klappt.


danielf - Di 27.04.10 15:19

Was willst du den mit dem Namen? Versuch es mal mit Text ...


chip777 - Di 27.04.10 15:29

Ich versuch es mal besser zu beschreiben. Wenn ich einen Knopf neben dem TreeView klicke, werden 2 Textboxen aktiviert.
In einer dieser TextBoxen steht anfangs der Inhalt aus dem TreeView, also Nodes.Text.
Diesen soll der Benutzer bearbeiten können. wenn der Button dann erneut geklickt wird, sollen die Änderungen übernommen werden. Das Problem ist jetzt: Immer wenn ich den Knopf drücke ist in meinem TreeView kein Knoten mehr selektiert.
und deshalb werden die beiden Codezeilen nicht ausgeführt.
Also müsste ich es hinbekommen das der Knoten selektiert bleibt, oder ich muss das irgendwie anders lösen.


danielf - Di 27.04.10 15:34

Was willst du den machen?

Was sind deine Ausgangsdaten?


chip777 - Di 27.04.10 15:40

Das wird ein längerer text werden, und das schaff ich in den 5 Minuten die ich noch hier bin nicht mehr, ich werd morgen versuchen die Gesamtsituation besser zu beschreiben.


danielf - Di 27.04.10 16:20

So früh würde ich auch gern Feierabend machen ;)

Bis Morgen


chip777 - Mi 28.04.10 07:53

Guten Morgen Daniel :-)

Ich darf nur so früh Feierabend machen, weil ich auch zeitig anfange (7.15 Uhr).
Ich hab mein Programm mal mit dem Debugger getestet, folgendes Problem besteht jetzt noch:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
foreach (TreeNode node in treeView1.Nodes)
                    {
                        if ((Int32)(node.Tag) == Id)
                        {
                            treeView1.SelectedNode = node;
                        }
                    }

Im Moment durchläuft die Schleife nur die erste Node, wie kann ich alle durchlaufen, du hattest etwas von rekursiv gesagt, ich weiß zwar was rekursion bedeutet, aber nicht wie ich diese hier einsetzen kann.


danielf - Mi 28.04.10 08:17

Guten Morgen,

da hast du wohl recht ;) (mit dem früh kommen früh gehen)

Also Rekursion ist ja eine Methode die sich selbst aufruft. D.h. als erstes brauchst du mal eine Methode aus der Schleife:

C#-Quelltext
1:
2:
3:
private void SetSelectedNode(TreeNodeCollection nodes, int id)
{
}


In der Methode machst du im Prinzip das gleiche. Nur nicht nur für die Nodes der ersten Ebene, sondern eben auch von den jeweils unteren Ebene:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
foreach(TreeNode node in nodes)
{
   if ((int) node.Tag == id)
   {
       treeView1.SelectedNode = node;
       // Vorgang abbrechen (es sollte ja nur ein Element mit TAG == ID geben);
       return;
   }
   // hier kommt nun die Rekursion für alle Unterelemente
   SetSelectedNode(node.Nodes, id);
}


Rekursion ist doch schön ;) um 8:17 Morgens .. hehe

Schönen Tag


chip777 - Mi 28.04.10 08:52

Juhu,

endlich funktioniert es so wie es soll, vielen lieben Dank.


danielf - Mi 28.04.10 08:59

Ach eine Anmerkung hab ich noch vergessen. Für das bessere Verständnis habe ich bei der Methodendeklaration das Mitschleifen der TreeView Instanz weggelassen. Das solltest du noch einbauen (private void SetSelectedNode(TreeView treeView, TreeNodeCollection nodes, int id) damit die Methode wiederverwendbar ist.