1

I have a TreeView with ContextMenuStrip (opening by right-click) ToolStripMenuItems with shortcuts like "Ctrl+C, Ctrl+V, etc."

The problem is that Action of ToolStripMenuItem.Click fires by shortcut only if ContextMenuStrip is opened.

I think that Shortcuts must work also when ContextMenuStip is hidden.

I do something wrong or ShortCuts are not global and I need to assign KeyPress event of TreeView and dublicate logic of shortcuts here? Thnx.

ForeverSmiling
  • 111
  • 3
  • 10

2 Answers2

3

I had the same problem and did not want to reprogram the access functions the ContextMenuStrip already offers me.

The big problem about that is, when I expand or change the ContextMenuStrip items, I have to alter or change my own Key-Events. My aim was to bypass this and redirect the global shortcut keys to the ContextMenuStrip to perform the click by code.

Firstly, I built a method that gets me all ToolStripMenuItems of the ContextMenuStrip in one list recursively:

    private List<ToolStripMenuItem> getContextMenuItems(ToolStripItemCollection items)
    {
        List<ToolStripMenuItem> result = new List<ToolStripMenuItem>();
        foreach (ToolStripMenuItem item in items)
        {
            result.Add(item);
            if (item.HasDropDownItems)
            {
                result.AddRange(this.getContextMenuItems(item.DropDownItems));
            }
        }
        return result;
    }

Then I set up the KeyUp event to catch my keys on a wrapper control. this.cmsCellRightClick is my ContextMenuStrip:

    private void xxxxx_KeyUp(object sender, KeyEventArgs e)
    {
        Keys pressed = e.KeyCode;
        if (e.Control) pressed = pressed | Keys.Control;
        if (e.Shift) pressed = pressed | Keys.Shift;
        if (e.Alt) pressed = pressed | Keys.Alt;

        ToolStripMenuItem actionItem = this.getContextMenuItems(this.cmsCellRightClick.Items)
            .Where(x => x.ShortcutKeys == pressed).FirstOrDefault();
        if (actionItem != null)
        {
            actionItem.PerformClick();
        }
        e.SuppressKeyPress = true;
    }

The result is it will catch my keystrokes and send them to my ContextMenuStrip and perform the click, even when the ContextMenuStrip is hidden / not open.

Martin Braun
  • 10,906
  • 9
  • 64
  • 105
  • The `getContextMenuItems` method can fail (raising an _InvalidCastException_) if you have separators in your context menu. This can be circumvented by using the generic `ToolStripItem` in the foreach loop and checking if casting to `ToolStripMenuItem` is successful. – Marcus Mangelsdorf Sep 22 '16 at 08:07
0

Yes you need to write a code for Treeview also may be Key Press or Key Down as per your requirement.

andy
  • 5,979
  • 2
  • 27
  • 49
  • It's strange, but args.KeyData in KeyDown TreeView event doesn't match combination I set to shortcut. It has extra KeyCodes of Modifiers. – ForeverSmiling Sep 28 '12 at 14:36
  • But I has been solved problem in whery stupid way: I set mistakenly same shortcuts to different menuItems. When I fix it I found that ContextMenuStrip Shortcuts works well if it is hidden.) – ForeverSmiling Sep 28 '12 at 14:39