Wie kann ich herausfinden, auf welchem Knoten in einer Baumliste das Kontextmenü aktiviert wurde? Klicken Sie beispielsweise mit der rechten Maustaste auf einen Knoten und wählen Sie eine Option aus dem Menü aus.
Ich kann die SelectedNode
Eigenschaft von TreeViews nicht verwenden, da der Knoten nur mit der rechten Maustaste angeklickt und nicht ausgewählt wurde.
Hier ist meine Lösung. Fügen Sie diese Zeile in das NodeMouseClick-Ereignis der TreeView ein:
quelle
Ich finde das Standardverhalten bei der Auswahl der Windows-Baumansicht ziemlich ärgerlich. Wenn Sie beispielsweise den Explorer verwenden und mit der rechten Maustaste auf einen Knoten klicken und auf Eigenschaften klicken, wird der Knoten hervorgehoben und der Eigenschaftendialog für den Knoten angezeigt, auf den Sie geklickt haben. Wenn Sie jedoch aus dem Dialogfeld zurückkehren, war der markierte Knoten der Knoten, der zuvor ausgewählt / hervorgehoben wurde, bevor Sie mit der rechten Maustaste geklickt haben. Ich finde, dass dies Usability-Probleme verursacht, weil ich für immer verwirrt bin, ob ich auf dem richtigen Knoten gehandelt habe.
In vielen unserer GUIs ändern wir den ausgewählten Baumknoten mit einem Rechtsklick, damit keine Verwirrung entsteht. Dies ist möglicherweise nicht dasselbe wie eine Standard-iwndos-App wie Explorer (und ich tendiere dazu, unser GUI-Verhalten aus Usabiltiy-Gründen stark nach Standard-Fenster-Apps zu modellieren). Ich glaube, dass dieser eine Ausnahmefall zu weitaus benutzerfreundlicheren Bäumen führt.
Hier ist ein Code, der die Auswahl beim Klicken mit der rechten Maustaste ändert:
private void tree_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) { // only need to change selected note during right-click - otherwise tree does // fine by itself if ( e.Button == MouseButtons.Right ) { Point pt = new Point( e.X, e.Y ); tree.PointToClient( pt ); TreeNode Node = tree.GetNodeAt( pt ); if ( Node != null ) { if ( Node.Bounds.Contains( pt ) ) { tree.SelectedNode = Node; ResetContextMenu(); contextMenuTree.Show( tree, pt ); } } } }
quelle
Wiederbelebung dieser Frage, weil ich dies für eine viel bessere Lösung halte. Ich benutze
NodeMouseClick
stattdessen das Ereignis.void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if( e.Button == MouseButtons.Right ) { tree.SelectedNode = e.Node; } }
quelle
Dies ist eine sehr alte Frage, aber ich fand sie trotzdem nützlich. Ich verwende eine Kombination einiger der oben genannten Antworten, da ich nicht möchte, dass der mit der rechten Maustaste angeklickte Knoten zum ausgewählten Knoten wird. Wenn ich den Stammknoten ausgewählt habe und eines seiner untergeordneten Knoten löschen möchte, möchte ich nicht, dass das untergeordnete Element ausgewählt wird, wenn ich es lösche (ich arbeite auch an dem ausgewählten Knoten, den ich nicht auf der rechten Seite ausführen möchte). klicken). Hier ist mein Beitrag:
// Global Private Variable to hold right-clicked Node private TreeNode _currentNode = new TreeNode(); // Set Global Variable to the Node that was right-clicked private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) _currentNode = e.Node; } // Do something when the Menu Item is clicked using the _currentNode private void toolStripMenuItem_Clicked(object sender, EventArgs e) { if (_currentNode != null) MessageBox.Show(_currentNode.Text); }
quelle
Ähnlich wie bei Marcus 'Antwort war dies die Lösung, die für mich funktioniert hat:
private void treeView_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { treeView.SelectedNode = treeView.GetNodeAt(e.Location); } }
Sie müssen das Kontextmenü nicht selbst anzeigen, wenn Sie es wie folgt auf jeden einzelnen Knoten einstellen:
TreeNode node = new TreeNode(); node.ContextMenuStrip = contextMenu;
Dann öffnet die TreeView.SelectedNode-Eigenschaft im Eröffnungsereignis des ContextMenu den richtigen Knoten.
quelle
Wenn Sie möchten, dass das Kontextmenü von dem ausgewählten Element abhängt, bewegen Sie sich am besten, indem Sie Jonesinators Code verwenden, um das angeklickte Element auszuwählen. Der Inhalt Ihres Kontextmenüs kann dann vom ausgewählten Element abhängen.
Die Auswahl des Elements zuerst und nicht nur die Verwendung für das Kontextmenü bietet einige Vorteile. Das erste ist, dass der Benutzer eine visuelle Anzeige hat, auf welche er geklickt hat und mit welchem Element das Menü verknüpft ist. Das zweite ist, dass es auf diese Weise viel einfacher ist, mit anderen Methoden zum Aufrufen des Kontextmenüs kompatibel zu bleiben (z. B. Tastaturkürzel).
quelle
Hier ist, wie ich es mache.
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) e.Node.TreeView.SelectedNode = e.Node; }
quelle
Eine andere Option, mit der Sie ausgeführt werden können, ist eine globale Variable mit dem ausgewählten Knoten. Sie müssten nur die verwenden
TreeNodeMouseClickEventArgs
.public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e) { _globalVariable = e.Node; }
Jetzt haben Sie Zugriff auf diesen Knoten und seine Eigenschaften.
quelle
Ich möchte eine Alternative zur Verwendung der Klickereignisse unter Verwendung des Ereignisses des Kontextmenüs vorschlagen
Opened
:private void Handle_ContextMenu_Opened(object sender, EventArgs e) { TreeViewHitTestInfo info = treeview.HitTest(treeview.PointToClient(Cursor.Position)); TreeNode contextNode; // was there a node where the context menu was opened? if (info != null && info.Node != null) { contextNode = info.Node; } // Set the enabled states of the context menu elements menuEdit.Enabled = contextNode != null; menuDelete.Enabled = contextNode != null; }
Dies hat die folgenden Vorteile, die ich sehen kann:
Hinweis: Wenn Sie befürchten, dass der Benutzer die Maus zum Zeitpunkt des Öffnens des Menüs bereits bewegt hat, können Sie
Opening
stattdessen das Ereignis verwenden.quelle