2008-08-05 18 views
61

¿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ú.Buscar nodo al que se hizo clic en el menú contextual

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

Respuesta

83

Puede agregar un evento de clic del mouse al TreeView, luego seleccione el nodo correcto usando GetNodeAt dadas las coordenadas del mouse provistas 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); 
     } 
    } 
} 
+4

Muchas gracias, tengo una pequeña adición a la solución: También podría usar el evento "_NodeMouseClick" que le da un "TreeNodeMouseClickEventArgs e", en cuyo caso puede usar el e.Node y no tiene molestarse en verificar si el nodo es nulo o no. – SDM

+0

Obtuve el resultado deseado con el evento MouseDown en lugar de MouseUp. – Javier

0

si desea que el menú contextual para depender de la opción seleccionada eres mejor movimiento que creo que es de usar el código de Jonesinator para seleccionar el elemento se ha hecho clic. El contenido del menú contextual puede depender del elemento seleccionado.

Seleccionar el elemento primero en lugar de solo usarlo para el menú contextual ofrece 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).

11

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.

Así que 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 en el botón derecho del ratón:

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); 
      } 
     } 
    } 
    } 
+0

Esta es la mejor solución para mí porque realmente selecciona el nodo en el que hizo clic. –

18

Aquí está mi solución. Poner esta línea en NodeMouseClick caso de TreeView:

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

El mouse evento args no tiene .Node –

+2

Sí, pero TreeNodeMouseClickEventArgs (que se pasan al evento ** NodeMouseClick **) sí. Así que mi solución está funcionando y no es demasiado complicada como en otras soluciones – deej

+1

Bueno y simple – AndrewJE

2

similares a la respuesta de Marcus, esta fue la solución que encontré trabajado para mí:

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

No es necesario mostrar el menú contextual sí mismo si configurarlo para que cada nodo individual, así:

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

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

6

Reanudando esta pregunta porque creo que esta es una solución mucho mejor. Uso el evento NodeMouseClick en su lugar.

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

igual que el mío =) – deej

+0

Me gusta mucho mejor también. –

0

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

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

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

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

Ahora tiene acceso a ese nodo y sus propiedades.

Cuestiones relacionadas