TreeView, TreeNode and ContextMenuStrip.SourceControl

Hi,

I want to use a context menu for nodes in several trees. It's fine to display the menu and handle the event, but the SourceControl property is always the TreeView itself, not the node the user clicked.

This would make sense to me if I had assigned the ContextMenuStrip property of the treeview, but I did not! I assign it to each tree node.

I now have to use an ugly workaround, handling the treeview's MouseUp event and tagging the context menu with the node as follows:

if (e.Button == MouseButtons.Right) {

ctxMenu.Tag = ((TreeView)ctxMenu.SourceControl).GetNodeAt(e.X, e.Y);

}

As the MouseUp event (of the TreeView) fires before the Click (of the ContextMenuStrip control) this works and I can now do things like call ExpandAll() on the node in question.

My question is WHY do I get the treeview as the source control when I assign the context menu only to the nodes and NOT to the treeview itself Is there a better way to obtain a reference to the (right-)clicked node

Using the selected node doesn't work as right-clicking doesn't change the selection (nor do I want it to; I just want to interact with the node).



Answer this question

TreeView, TreeNode and ContextMenuStrip.SourceControl

  • chaza

    I'd recommend you file a bug report at Product Feedback.

  • MA2005

    Unlike you I didn't reverse-engineer the code :) but I *did* check whether the selectednode had been set. I can assure you that it is not, neighter when the ContextMenuItem_Click event fires nor at any later point in time. If I only click the "+" boxes to expand nodes and otherwise just right-click nodes, SelectedNode remains null.

    I frankly think this is a poor design to say the least. I'm not saying the TreeNode should necessarily derive from Control; but if there are good reasons why it does not the information should be provided as event data. It's almost comical when I find myself missing DHTML features (event.srcElement in this case) when doing Windows Forms programming rather than the other way around...

    Thankfully the workaround seems to be fine, but it does of course add slight overhead. My real gripe with it is that it's a bit too close to voodoo programming; it's not a logical way to do what I wanted to do.


  • Brandon Bloom

    SourceControl is a reference to a Control instance. TreeNodes are not derived from Control so only the treeview instance can be used.

    Your last remark is puzzling; the code in the framework that displays the ContextMenuStrip explicitly selects the right-clicked node. I'm sure that was done intentionally so you could use the TreeView.SelectedNode property to find out what node should be affected by the menu commands. That selection is done with a PostMessage() call so it won't be made yet by the time you see the MouseUp event.


  • TreeView, TreeNode and ContextMenuStrip.SourceControl