Encontrar el nodo al que se hizo clic en el menú contextual

¿Cómo puedo averiguar qué nodo en una lista de árbol se ha activado el menú contextual? Por ejemplo, haga clic derecho en un nodo y seleccione una opción del menú.

No puedo usar la propiedad SelectedNode TreeViews porque el nodo solo se ha hecho clic derecho y no se ha seleccionado.

Puede agregar un evento de clic del mouse al TreeView, luego seleccionar el nodo correcto usando GetNodeAt dadas las coordenadas del mouse proporcionadas por MouseEventArgs.

 void treeView1MouseUp(object sender, MouseEventArgs e) { if(e.Button == MouseButtons.Right) { // Select the clicked node treeView1.SelectedNode = treeView1.GetNodeAt(eX, eY); if(treeView1.SelectedNode != null) { myContextMenuStrip.Show(treeView1, e.Location); } } } 

Aquí está mi solución. Coloque esta línea en el evento NodeMouseClick de TreeView:

  ((TreeView)sender).SelectedNode = e.Node; 

Encuentro que el comportamiento de selección de comportamiento estándar de windows tree es bastante molesto. Por ejemplo, si está utilizando Explorer y hace clic derecho en un nodo y pulsa Propiedades, resalta el nodo y muestra el diálogo de propiedades para el nodo en el que hizo clic. Pero cuando regresa del diálogo, el nodo resaltado era el nodo previamente seleccionado / resaltado antes de hacer clic con el botón derecho. Encuentro que esto causa problemas de usabilidad porque siempre estoy confundido sobre si actué en el nodo correcto.

Entonces, en muchas de nuestras GUI, cambiamos el nodo de árbol seleccionado haciendo clic con el botón derecho para que no haya confusión. Puede que no sea lo mismo que una aplicación iwndos estándar como Explorer (y tiendo a modelar fuertemente nuestro comportamiento de GUI después de las aplicaciones de ventana estándar por razones de usabilidad), creo que este caso de excepción da como resultado árboles mucho más utilizables.

Aquí hay un código que cambia la selección con el clic derecho:

  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( eX, eY ); tree.PointToClient( pt ); TreeNode Node = tree.GetNodeAt( pt ); if ( Node != null ) { if ( Node.Bounds.Contains( pt ) ) { tree.SelectedNode = Node; ResetContextMenu(); contextMenuTree.Show( tree, pt ); } } } } 

Revivir esta pregunta porque creo que esta es una solución mucho mejor. Yo uso el evento NodeMouseClick lugar.

 void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if( e.Button == MouseButtons.Right ) { tree.SelectedNode = e.Node; } } 

Al igual que la respuesta de Marcus, esta fue la solución que encontré funcionó para mí:

 private void treeView_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { treeView.SelectedNode = treeView.GetNodeAt(e.Location); } } 

No necesita mostrar el menú contextual usted mismo si lo establece en cada nodo individual de la siguiente manera:

 TreeNode node = new TreeNode(); node.ContextMenuStrip = contextMenu; 

Luego, dentro del evento Opening del ContextMenu, la propiedad TreeView.SelectedNode reflejará el nodo correcto.

Esta es una pregunta muy antigua, pero aún así la encontré útil. Estoy usando una combinación de algunas de las respuestas anteriores, porque no quiero que el nodo al que se hace clic con el botón derecho se convierta en elNodo seleccionado. Si selecciono el nodo raíz y deseo eliminar uno de sus elementos secundarios, no quiero que se seleccione el elemento secundario cuando lo elimine (también estoy trabajando en elNodo seleccionado que no deseo que ocurra en un elemento hacer clic). Aquí está mi contribución:

 // 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); } 

Si desea que el menú contextual dependa del elemento seleccionado, lo mejor es mudarse, creo que es utilizar el código de Jonesinator para seleccionar el elemento que se está haciendo clic. El contenido del menú contextual puede depender del elemento seleccionado.

Seleccionar el elemento primero en lugar de simplemente usarlo para el menú contextual brinda algunas ventajas. La primera es que el usuario tiene una indicación visual de en qué clic y, por lo tanto, con qué elemento está asociado el menú. El segundo es que de esta manera es mucho más fácil mantener compatible con otros métodos de invocación del menú contextual (por ejemplo, atajos de teclado).

Así es como lo hago.

 private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) e.Node.TreeView.SelectedNode = e.Node; } 

Otra opción con la que puede ejecutar es tener una variable global que tenga el nodo seleccionado. Solo necesitaría usar TreeNodeMouseClickEventArgs .

 public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e) { _globalVariable = e.Node; } 

Ahora tiene acceso a ese nodo y sus propiedades.