2008-08-05 14 views
61

Come individuare quale nodo in una struttura ad albero è stato attivato il menu di scelta rapida? Ad esempio, fare clic con il pulsante destro del mouse su un nodo e selezionare un'opzione dal menu.Trova nodo selezionato nel menu di scelta rapida

Non riesco a utilizzare la proprietà SelectedNode di TreeViews perché il nodo è stato solo fatto clic con il pulsante destro del mouse e non è stato selezionato.

risposta

83

È possibile aggiungere un evento di clic del mouse a TreeView, quindi selezionare il nodo corretto utilizzando GetNodeAt in base alle coordinate del mouse fornite da 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

Grazie mille, ho una piccola aggiunta alla soluzione: Puoi anche utilizzare l'evento "_NodeMouseClick" che ti dà un "TreeNodeMouseClickEventArgs e" nel qual caso puoi semplicemente usare il nodo e.Node e non hai preoccuparsi di controllare se il nodo è nullo o no. – SDM

+0

Ho ottenuto il risultato desiderato con l'evento MouseDown invece di MouseUp. – Javier

0

Se si desidera che il menu contestuale di essere dipendente dalla voce selezionata sei mossa migliore credo è quello di utilizzare il codice di Jonesinator per selezionare la voce cliccato. Il contenuto del menu contestuale può quindi dipendere dall'elemento selezionato.

Selezionare prima l'elemento invece di usarlo solo per il menu di scelta rapida offre alcuni vantaggi. Il primo è che l'utente ha un'indicazione visiva su cui ha fatto clic e quindi su quale voce è associato il menu. La seconda è che in questo modo è molto più facile mantenere la compatibilità con altri metodi di richiamo del menu di scelta rapida (ad esempio le scorciatoie da tastiera).

11

Trovo che il comportamento di selezione del comportamento di Windows Vista standard sia piuttosto fastidioso. Ad esempio, se si utilizza Esplora risorse e si fa clic con il pulsante destro del mouse su un nodo e si preme Proprietà, viene evidenziato il nodo e viene visualizzata la finestra di dialogo delle proprietà per il nodo su cui si è fatto clic. Ma quando si ritorna dalla finestra di dialogo, il nodo evidenziato era il nodo precedentemente selezionato/evidenziato prima di fare clic con il tasto destro. Trovo che questo causi problemi di usabilità perché sono sempre confuso dal fatto che io abbia agito sul nodo giusto.

Quindi in molte delle nostre GUI, cambiamo il nodo dell'albero selezionato con un clic destro, in modo che non ci sia confusione. Questo potrebbe non essere lo stesso di un'app standard di iwndos come Explorer (e io tendo a modellare fortemente il comportamento della GUI dopo le app per finestre standard per motivi di utilità), credo che questo caso di eccezione si traduca in alberi molto più utilizzabili.

Ecco alcuni codice che cambia la selezione durante il tasto destro del mouse:

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

Questa è la soluzione migliore per me perché in realtà seleziona il nodo su cui hai fatto clic. –

18

Ecco la mia soluzione. Metti questa linea nel NodeMouseClick caso di TreeView:

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

Gli argomenti dell'evento del mouse non hanno. Nodo –

+2

Sì, ma TreeNodeMouseClickEventArgs (che vengono passati in ** evento NodeMouseClick **). Quindi la mia soluzione funziona e non è complicata come alcune altre soluzioni – deej

+1

Bello e semplice – AndrewJE

2

Simile alla risposta di Marcus', questa era la soluzione che ho trovato lavorato per me:

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

Non è necessario mostrare il menu di scelta rapida da soli se si impostare per ogni singolo nodo in questo modo:

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

Poi all'interno evento di apertura del ContextMenu, la proprietà TreeView.SelectedNode rifletterà nodo corretto.

6

Riattivare questa domanda perché ritengo che sia una soluzione molto migliore. Io uso invece l'evento NodeMouseClick.

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

uguale al mio =) – deej

+0

Mi piace molto anche questo. –

0

Ecco come lo faccio.

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

Questa è una domanda molto vecchia, ma l'ho trovata ancora utile.Sto usando una combinazione di alcune delle risposte di cui sopra, perché non voglio che il nodo con clic destro diventi il ​​SelectedNode. Se ho il nodo radice selezionato e voglio cancellare uno dei suoi figli, non voglio che il bambino venga selezionato quando lo elimino (sto anche facendo un po 'di lavoro sul SelectedNode che non voglio succedere su un diritto- clic). Qui è il mio contributo:

// 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

Un'altra opzione è possibile eseguire con è quello di avere una variabile globale che ha il nodo selezionato. Dovresti solo usare lo TreeNodeMouseClickEventArgs.

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

Ora si ha accesso a quel nodo e alle sue proprietà.