Trova nodo cliccato nel menu di scelta rapida

Come posso scoprire quale nodo in una lista ad albero è stato triggersto il menu di scelta rapida? Ad esempio, fare clic con il pulsante destro del mouse su un nodo e selezionare un’opzione dal menu.

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

È ansible 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(eX, eY); if(treeView1.SelectedNode != null) { myContextMenuStrip.Show(treeView1, e.Location); } } } 

Ecco la mia soluzione. Metti questa linea nell’evento NodeMouseClick di TreeView:

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

Trovo abbastanza normale il comportamento di selezione del comportamento in treeview delle windows standard. 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.

Pertanto, in molte delle nostre GUI, modifichiamo 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 windows standard per motivi di utilità), credo che questo caso di eccezione si traduca in alberi molto più utilizzabili.

Ecco un codice che modifica la selezione durante il clic destro:

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

Rivedendo questa domanda perché trovo che questa 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; } } 

Simile alla risposta di Marcus, questa è stata la soluzione che ho trovato 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 contestuale da soli se lo si imposta su ogni singolo nodo in questo modo:

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

Quindi, all’interno dell’evento Opening di ContextMenu, la proprietà TreeView.SelectedNode rifletterà il nodo corretto.

Questa è una domanda molto vecchia, ma l’ho trovata comunque 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). Ecco 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); } 

Se si desidera che il menu di scelta rapida dipenda dall’elemento selezionato, si consiglia di utilizzare il codice di Jonesinator per selezionare l’elemento selezionato. Il contenuto del menu contestuale può quindi dipendere dall’elemento selezionato.

Selezionare prima l’object 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. Il secondo è che in questo modo è molto più facile mantenere la compatibilità con altri metodi di richiamo del menu di scelta rapida (ad es. Scorciatoie da tastiera).

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

Un’altra opzione che potresti eseguire è avere una variabile globale che ha il nodo selezionato. Dovresti solo usare TreeNodeMouseClickEventArgs .

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

Ora hai accesso a quel nodo e alle sue proprietà.