Search code examples
c#menuitemmenustrip

How to align some MenuItems to the right with MenuStrip LayoutStyle set to Flow?


I would like to make it so that some of the buttons on a MenuStrip aligned to the right of the MenuStrip. For example, Focus ON and Focus OFF on the right side of the menu strip:

MenuStrip

I can get this to work if I set the MenuStrip's LayoutStyle to StackWithOverFlow, but then if the window size is decreased the menu items get cropped:

MenuStrip with LayoutStyle set to StackWithOverFlow

How can I make it so that I can align the menu items to the right with the MenuStrip LayoutStyle set to Flow? That way, when the form size decreases, the menu items go to the next line?

Also, how can I make it that the other controls are pushed down a little bit when the MenuStrip makes a new line for more menu items?


Solution

  • In order to right-align some menu items, you need to set the item's Alignment value to Right. However, right alignment only applies in the StackWithOverflow layout styles. If you are using Flow alignment style, then the items will always flow from left-to-right.

    Also, when you right-align items in StackWithOverflow layout style, the item flow from the outside in, so if your original layout is 1 2 3 4 5, your right-aligned items would be 1 2 3 <gap> 5 4.

    The solution to your problem is in two parts:

    1. Track the SizeChanged event to determine if you need Flow or StackWithOverflow based on the width of all menu items and the available width of the window.

    2. If you have to change the layout style, swap the right-aligned items so that they appear in the correct order in either layout style.

      private void Form1_SizeChanged(object sender, EventArgs e)
      {
          int width = 0;
      
          // add up the width of all items in the menu strip
          foreach (ToolStripItem item in menuStrip1.Items)
              width += item.Width;
      
          // get the current layout style
          ToolStripLayoutStyle oldStyle = menuStrip1.LayoutStyle;
      
          // determine the new layout style
          ToolStripLayoutStyle newStyle = (width < this.ClientSize.Width)
              ? menuStrip1.LayoutStyle = ToolStripLayoutStyle.StackWithOverflow
              : menuStrip1.LayoutStyle = ToolStripLayoutStyle.Flow;
      
          // do we need to change layout styles?
          if (oldStyle != newStyle)
          {
              // update the layout style
              menuStrip1.LayoutStyle = newStyle;
      
              // swap the last item with the second-to-last item
              int last = menuStrip1.Items.Count - 1;
              ToolStripItem item = menuStrip1.Items[last];
              menuStrip1.Items.RemoveAt(last);
              menuStrip1.Items.Insert(last - 1, item);
          }
      }
      

    The process of swapping the right-aligned items will have to be adapted more carefully if you have more than two items. The code above simply swaps them, but if you have three or more items, you'll need to reverse their order entirely.