Buscar nodo en el que se hizo clic en el menú contextual


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

No puedo usar la propiedad TreeViews' SelectedNode porque el nodo solo se hace clic con el botón derecho y no se selecciona.

Author: Sebastian Negraszus, 2008-08-05

9 answers

Puede agregar un evento de clic del ratón al TreeView, luego seleccionar el nodo correcto usando GetNodeAt dadas las coordenadas del ratón proporcionadas por los 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);
        }
    }
}
 83
Author: Jonesinator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-11 05:38:54

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

 ((TreeView)sender).SelectedNode = e.Node;
 19
Author: deej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-08 23:05:57

Encuentro que el comportamiento estándar de selección de comportamiento de windows treeview es bastante molesto. Por ejemplo, si está utilizando el Explorador y hace clic con el botón 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 regrese del cuadro de diálogo, el nodo resaltado fue el nodo previamente seleccionado/resaltado antes de hacer clic con el botón derecho. Me parece que esto causa problemas de usabilidad porque siempre estoy confundido sobre si actué en el nodo derecho.

Así que en muchas de nuestras GUI, cambiamos el nodo de á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 aplicaciones de ventana estándar por razones de usabiltiy), creo que este caso de excepción resulta en á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 );
           }
        }
     }
  }
 12
Author: Marcus Erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-15 00:53:58

Reviviendo esta pregunta porque encuentro que esta es una solución mucho mejor. Utilizo el evento NodeMouseClick en su lugar.

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}
 6
Author: Beta Carotin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-02 19:41:00

Similar a 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 de Apertura del ContextMenu, el TreeView.La propiedad SelectedNode reflejará el nodo correcto.

 2
Author: Trevor Elliott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-21 22:10:51

Esta es una pregunta muy antigua, pero todavía la encontré útil. Estoy usando una combinación de algunas de las respuestas anteriores, porque no quiero que el nodo del botón derecho se convierta en el SelectedNode. Si tengo el nodo raíz seleccionado y quiero eliminar uno de sus hijos, no quiero que el hijo seleccionado cuando lo elimine (también estoy haciendo algún trabajo en el SelectedNode que no quiero que suceda con un clic derecho). 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);
}
 2
Author: George,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-06 19:42:55

Si desea que el menú contextual dependa del elemento seleccionado, creo que es mejor que use 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 simplemente usarlo para el menú contextual da algunas ventajas. La primera es que el usuario tiene una indicación visual de a qué ha hecho clic y, por lo tanto, a qué elemento está asociado el menú. La segunda es que de esta manera es un infierno de mucho más fácil de mantener compatible con otros métodos de invocar el menú contextual (por ejemplo, atajos de teclado).

 0
Author: ICR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-08 14:04:11

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;
}
 0
Author: Ricky Manwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-29 22:11:10

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

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

Ahora tienes acceso a ese nodo y sus propiedades.

 0
Author: sparkyShorts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-12 20:30:56