Question

I have a menu of items that the user can toggle. I wanted the menu to stay open so the user can check all the items they want. I set autoclose = false and now that works great. However, I also cannot close the window now lol. I tried clicking off of the menu onto the form, hitting escape, hitting the menu item, hitting the keycombo for the menu, nothing works.

Ideally, I'd like the user to be able to just click the form or basically anything but the menu to close it or press escape. How would I accomplish that? I tried creating a gotfocus event on the form and doing item.HideDropDown in there but no dice.

Thanks!

Was it helpful?

Solution

Generate the click event for the form, and then go through and for every control that doesn't have its own click event, set its click event to the one for the form.

In the event, include the code to hide the menu: toolStripDropDownButton.HideDropDown();

Copy the code to any existing click events for other controls.

This is how I handled hiding a monthcalendar when you click anywhere on the form.

And if you want to also include pressing escape as an option, do the same thing with a KeyDown event, checking if it's the escape key before running the code.

OTHER TIPS

I had similar problem, and here is my solution. I created common MouseEnter and MouseLeave event handlers and used a timer to delay-close the menu after mouse leaves it.

Below is a sample code for the menu of 3 items and 1 separator. In the sample 2 items work with AutoClose and one (the _modeChangingItem) does not close the menu. You can easily customize this for your needs, e.g. make none of the items AutoClose.

private Timer _menuTimer = new Timer();

private void MainFrm_Load (object sender, EventArgs e)
{
    _menuTimer.Interval = 200;
    _menuTimer.Tick += _menuTimer_Tick;

    _rootMenuItem.MouseEnter += commonMenu_MouseEnter;
    _rootMenuItem.MouseLeave += commonMenu_MouseLeave;

    _menuItem1.MouseEnter += commonMenu_MouseEnter;
    _menuItem1.MouseLeave += commonMenu_MouseLeave;
    _menuItem2.MouseEnter += commonMenu_MouseEnter;
    _menuItem2.MouseLeave += commonMenu_MouseLeave;
    _separator.MouseEnter += commonMenu_MouseEnter;
    _separator.MouseLeave += commonMenu_MouseLeave;
    _modeChangingItem.MouseEnter += commonMenu_MouseEnter;
    _modeChangingItem.MouseLeave += commonMenu_MouseLeave;

}

private void commonMenu_MouseLeave(object sender, EventArgs e)
{
    _menuTimer.Stop();

    // Comment this line out if you want none of the items to AutoClose 
    _rootMenuItem.DropDown.AutoClose = true;

    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem != null) menuItem.Tag = null;
    ToolStripSeparator separator = sender as ToolStripSeparator;
    if (separator != null) separator.Tag = null;
    _menuTimer.Start();
}

private void commonMenu_MouseEnter(object sender, EventArgs e)
{
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem != null) menuItem.Tag = new object();
    ToolStripSeparator separator = sender as ToolStripSeparator;
    if (separator != null) separator.Tag = new object();
}

private void _menuTimer_Tick(object sender, EventArgs e)
{
    if (_rootMenuItem.Tag == null && _menuItem1.Tag == null &&
                                     _menuItem2.Tag == null &&
                                     _separator.Tag == null &&
                                     _modeChangingItem.Tag == null)
    {
        _rootMenuItem.DropDown.Close();
    }
    _menuTimer.Stop();
}

private void _modeChangingItem_Click(object sender, EventArgs e)
{
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem == null) return;

    // Move this line to Form_Load if you want none of the items AutoClose 
    _rootMenuItem.DropDown.AutoClose = false; // Now the menu stays opened

    [...]
}

This solution saves extra click for user - the timer closes the menu when you move mouse outside of all the items.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top