Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent ToolStripMenuItems from jumping to second screen

I have an application that is mostly operated through NotifyIcon's ContextMenuStrip
There are multiple levels of ToolStripMenuItems and the user can go through them.
The problem is, that when the user has two screen, the MenuItems jump to second screen when no space is available. like so:

enter image description here

How can I force them to stay on the same screen? I've tried to search through the web but couldn't find an appropriate answer.

Here is a sample piece of code i'm using to test this senario:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();

        var resources = new ComponentResourceManager(typeof(Form1));
        var notifyIcon1 = new NotifyIcon(components);
        var contextMenuStrip1 = new ContextMenuStrip(components);
        var level1ToolStripMenuItem = new ToolStripMenuItem("level 1 drop down");
        var level2ToolStripMenuItem = new ToolStripMenuItem("level 2 drop down");
        var level3ToolStripMenuItem = new ToolStripMenuItem("level 3 drop down");

        notifyIcon1.ContextMenuStrip = contextMenuStrip1;
        notifyIcon1.Icon = ((Icon)(resources.GetObject("notifyIcon1.Icon")));
        notifyIcon1.Visible = true;

        level2ToolStripMenuItem.DropDownItems.Add(level3ToolStripMenuItem);
        level1ToolStripMenuItem.DropDownItems.Add(level2ToolStripMenuItem);
        contextMenuStrip1.Items.Add(level1ToolStripMenuItem);
    }
}
like image 914
atlanteh Avatar asked Oct 20 '22 23:10

atlanteh


1 Answers

It is not easy, but you can write code in the DropDownOpening event to look at where the menu is at (its bounds), the current screen, and then set the DropDownDirection of the ToolStripMenuItem:

private void submenu_DropDownOpening(object sender, EventArgs e)
{
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem.HasDropDownItems == false)
    {
        return; // not a drop down item
    }
    // Current bounds of the current monitor
    Rectangle Bounds = menuItem.GetCurrentParent().Bounds;
    Screen CurrentScreen = Screen.FromPoint(Bounds.Location);
    // Look how big our children are:
    int MaxWidth = 0;
    foreach (ToolStripMenuItem subitem in menuItem.DropDownItems)
    {
        MaxWidth = Math.Max(subitem.Width, MaxWidth);
    }
    MaxWidth += 10; // Add a little wiggle room

    int FarRight = Bounds.Right + MaxWidth;
    int CurrentMonitorRight = CurrentScreen.Bounds.Right;

    if (FarRight > CurrentMonitorRight)
    {
        menuItem.DropDownDirection = ToolStripDropDownDirection.Left;
    }
    else
    {
        menuItem.DropDownDirection = ToolStripDropDownDirection.Right;
    }
}

Also, make sure you have the DropDownOpening event hooked up (you would really need to add this to every menu item):

level1ToolStripMenuItem += submenu_DropDownOpening;
like image 120
David Avatar answered Oct 22 '22 13:10

David