c# winforms treeview contextmenu

c# - Haga clic en el nodo Buscar en el menú contextual



winforms treeview (9)

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

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

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

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


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


Encuentro que el comportamiento estándar de selección de comportamiento de vista de árbol de Windows es bastante molesto. Por ejemplo, si está utilizando Explorer y hace clic derecho en un nodo y presiona Propiedades, resalta el nodo y muestra el cuadro de diálogo de propiedades para el nodo en el que hizo clic. Pero cuando regresa del cuadro de diálogo, el nodo resaltado era el nodo previamente seleccionado / resaltado antes de hacer clic con el botón derecho. Creo 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 del árbol seleccionado con un clic derecho para que no haya confusión. Esto puede no ser lo mismo que una aplicación iwndos estándar como Explorer (y tiendo a modelar fuertemente nuestro comportamiento 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 durante 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( 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 ); } } } }


Esta es una pregunta muy antigua, pero aún la encuentro útil. Estoy usando una combinación de algunas de las respuestas anteriores, porque no quiero que el nodo con el botón derecho se convierta en el nodo seleccionado. Si tengo el nodo raíz seleccionado y quiero eliminar uno de sus hijos, no quiero que se seleccione el hijo cuando lo elimine (también estoy haciendo un trabajo en el nodo seleccionado que no quiero que ocurra a la derecha) 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); }


Otra opción con la que podría 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.


Puede agregar un evento de clic del mouse a 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(e.X, e.Y); if(treeView1.SelectedNode != null) { myContextMenuStrip.Show(treeView1, e.Location); } } }


Revivir esta pregunta porque considero que 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; } }


Si desea que el menú contextual dependa del elemento seleccionado, es mejor moverlo, creo que es usar el código de Jonesinator para seleccionar el elemento seleccionado. El contenido del menú contextual puede depender del elemento seleccionado.

Seleccionar el elemento primero en lugar de usarlo solo para el menú contextual ofrece algunas ventajas. La primera es que el usuario tiene una indicación visual de en qué hizo clic y, por lo tanto, a qué elemento está asociado el menú. La segunda es que de esta manera es mucho más fácil mantenerse compatible con otros métodos para invocar el menú contextual (por ejemplo, atajos de teclado).


Similar a la respuesta de Marcus, esta fue la solución que encontré que 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 configura en cada nodo individual de la siguiente manera:

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

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