コンテキスト メニューでクリックされたノードの検索
-
08-06-2019 - |
質問
ツリー リスト内のどのノードでコンテキスト メニューがアクティブになっているかを確認するにはどうすればよいですか?たとえば、ノードを右クリックしてメニューからオプションを選択します。
TreeView は使用できません SelectedNode
これは、ノードが右クリックされただけで選択されていないためです。
解決
TreeView にマウス クリック イベントを追加し、MouseEventArgs によって提供されるマウス座標を指定して GetNodeAt を使用して正しいノードを選択できます。
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);
}
}
}
他のヒント
これが私の解決策です。次の行を TreeView の NodeMouseClick イベントに追加します。
((TreeView)sender).SelectedNode = e.Node;
Windows の標準のツリービュー動作の選択動作は非常に煩わしいと思います。たとえば、エクスプローラーを使用しているときにノードを右クリックして [プロパティ] をクリックすると、ノードが強調表示され、クリックしたノードのプロパティ ダイアログが表示されます。ただし、ダイアログから戻ったとき、強調表示されたノードは、右クリックする前に選択/強調表示されていたノードです。正しいノードを操作したかどうかについて永遠に混乱するため、これがユーザビリティの問題を引き起こすことがわかりました。
そのため、多くの GUI では、混乱が生じないよう、選択したツリー ノードを右クリックで変更します。これは、Explorer のような標準の iwndos アプリと同じではないかもしれません (そして、私は使いやすさの理由から、標準のウィンドウ アプリに倣って GUI の動作を強くモデル化する傾向があります)。この 1 つの例外ケースにより、はるかに使いやすいツリーが生成されると思います。
右クリック中に選択内容を変更するコードを次に示します。
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 );
}
}
}
}
これがはるかに優れた解決策であることがわかったので、この質問を復活させます。私が使用するのは、 NodeMouseClick
代わりにイベント。
void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if( e.Button == MouseButtons.Right )
{
tree.SelectedNode = e.Node;
}
}
マーカスの答えと同様に、これが私にとってうまくいった解決策でした。
private void treeView_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
treeView.SelectedNode = treeView.GetNodeAt(e.Location);
}
}
次のように個々のノードにコンテキスト メニューを設定する場合は、コンテキスト メニューを自分で表示する必要はありません。
TreeNode node = new TreeNode();
node.ContextMenuStrip = contextMenu;
次に、ContextMenu のオープニング イベント内で、TreeView.SelectedNode プロパティに正しいノードが反映されます。
これは非常に古い質問ですが、それでも役に立ちます。右クリックしたノードを selectedNode にしたくないため、上記の回答のいくつかを組み合わせて使用しています。ルート ノードを選択しており、その子の 1 つを削除したい場合、削除時に子が選択されることは望ましくありません (また、selectedNode に対して右側で発生したくない作業を行っています。クリック)。私の貢献は次のとおりです。
// 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);
}
コンテキスト メニューを選択した項目に依存させたい場合は、Jonesinator のコードを使用してクリックされた項目を選択するのが最善の策だと思います。コンテキスト メニューの内容は、選択した項目に依存するようになります。
単にコンテキスト メニューとして使用するのではなく、最初に項目を選択すると、いくつかの利点があります。1 つ目は、ユーザーがどの項目をクリックしたか、つまりメニューがどの項目に関連付けられているかを視覚的に示すことができることです。2 つ目は、この方法により、コンテキスト メニューを呼び出す他の方法 (例:キーボードショートカット)。
これが私のやり方です。
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
e.Node.TreeView.SelectedNode = e.Node;
}
実行できるもう 1 つのオプションは、選択したノードを含むグローバル変数を使用することです。を使用するだけです。 TreeNodeMouseClickEventArgs
.
public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e)
{
_globalVariable = e.Node;
}
これで、そのノードとそのプロパティにアクセスできるようになりました。