none
TreeView, TreeNode and ContextMenuStrip.SourceControl RRS feed

  • Question

  • 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).

     

    Wednesday, December 20, 2006 12:12 PM

Answers

  • 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.
    Wednesday, December 20, 2006 1:14 PM
    Moderator

All replies

  • 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.
    Wednesday, December 20, 2006 1:14 PM
    Moderator
  • 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.

    Wednesday, December 20, 2006 8:31 PM
  • I'd recommend you file a bug report at Product Feedback.
    Wednesday, December 20, 2006 8:57 PM
    Moderator