I am very new to .NET and I had to write a program in which there is a TreeView with different kind of nodes, Each kind of node has a different ContextMenuStrip, So I create multiple kind of ContextMenuStrip and assign then to different kind of TreeNode. Now my question is, when user show a context menu how should I find which TreeNode was the node that cause ContextMenuStrip to show. I try to use ContextMenuStrip.SourceControl
but it return a TreeView and it never help me, because I know that my source is TreeView I want to know which node of the view! Now should I use some kind of hit test? and if yes what about ContextMenu that shown using keyboard?
Asked
Active
Viewed 355 times
0

BigBoss
- 6,904
- 2
- 23
- 38
-
Possible duplicate of [ContextMenuStrip.Owner Property null When Retrieving From Nested ToolStripMenuItem](http://stackoverflow.com/questions/12094528/contextmenustrip-owner-property-null-when-retrieving-from-nested-toolstripmenuit) – Rowland Shaw Jan 07 '16 at 12:00
-
How is it related to that question?? did you ever read the question? I want to find a node that caused the instantiation of the menu. How is it related to finding a menu from its items???? – BigBoss Jan 09 '16 at 11:27
1 Answers
0
You may use Tag property to "link" the source nodes. For example, in your form's Load event handler:
private void Form1_Load(object sender, EventArgs e)
{
TreeNode rootNode = treeView1.Nodes[0];
rootNode.Nodes[0].ContextMenuStrip = contextMenuStrip1;
contextMenuStrip1.Tag = rootNode.Nodes[0];
rootNode.Nodes[1].ContextMenuStrip = contextMenuStrip2;
contextMenuStrip2.Tag = rootNode.Nodes[1];
}
Then you can bind all ContextMenuStrip controls' Opened event handlers to one method, as below:
private void contextMenuStrip_Opened(object sender, EventArgs e)
{
ContextMenuStrip cms = sender as ContextMenuStrip;
TreeNode aNode = cms.Tag as TreeNode;
if (aNode != null)
{
MessageBox.Show(aNode.Text);
}
}
There might be better ways to do it, but I think this should be able to solve your problem.
Updated 2012-10-17:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
contextMenuStrip1.Tag = e.Node;
}
}
private void contextMenuStrip1_Opened(object sender, EventArgs e)
{
ContextMenuStrip cms = sender as ContextMenuStrip;
TreeNode aNode = cms.Tag as TreeNode;
if (aNode == null)
{
aNode = treeView1.SelectedNode;
}
MessageBox.Show(aNode.Text);
}
private void contextMenuStrip1_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
ContextMenuStrip cms = sender as ContextMenuStrip;
cms.Tag = null;
}

Michael Tsai
- 661
- 7
- 17
-
In this way an according to your code I should use a dozen of ContextMenuStrip for a dozen of nodes!! But I only have on ContextMenuStrip per type of node and that's the source of problem – BigBoss Oct 16 '12 at 12:38
-
I don't see where is the difference between one and multiple ContextMenuStrip controls. With the same method that uses Tag property, you should have enough control for the event source. Or maybe I missed something. If you would show some code, I might know where is the problem. – Michael Tsai Oct 16 '12 at 15:01
-
When you have multiple ContextMenuStrip you can set `Tag` property for each ContextMenuStrip to an specific Node, but otherwise, you just have one ContextMenuStrip for many nodes. Now how you should set Tag to appropriate node?? – BigBoss Oct 16 '12 at 16:01
-
I see what you mean. I have also read the comments from Hans Passant and you. I already update my answer. Please see if the new code solved your problem (the user should be able to use keyboard and mouse to open the context menu). – Michael Tsai Oct 16 '12 at 17:38
-
This solution doesn't work if the end user users a keyboard accelerator for an item on the menu (e.g. if you've got the `ShortcutKeys` property set on a `ToolStripMenuItem` within the `ContextMenuStrip`) – Rowland Shaw Jan 07 '16 at 12:00