I'm using .net 2.0 with Visual Studio 2005 and I am trying to add two different toolstrips to the top of the form such that they show up side-by-side. I want it to be like Word 2003, where you can add multiple toolstrips to the same row and have them show up in line with each other, rather than dedicating a row to each toolstrip.
So I added a ToolStripPanel and docked it to the top of the form (I didn't use a ToolStripContainer because I don't need all the extra panels; I just need the one at the top). I added both toolstrips and set their Stretch properties to False. I can get them to show up in the designer window side-by-side, but at runtime the ToolStripPanel separates the toolstrips and gives each toolstrip its own dedicated row. As if to add insult to injury, when i stop debugging and return back to the designer, I am finding that the designer is moving the toolstrips to their own row as well! Am I doing something wrong here?
I have been Googling all day and found some information about a ToolStripPanelRow object, but I don't see an easy way to add toolstrips to it (i.e. it doesn't have a ToolStripPanelRow.Controls.Add method or anything like that), all it has is a Controls() property that returns an Array of control objects, and I haven't had much luck trying to add items to that array. I also found some documentation on the ToolStripPanel.Join method, which sounds like it should do the job, so I tried all 3 overloads but they don't work as advertised. No matter what I do or which options I try, it always adds the new toolstrip to the top of the panel on its own row and pushes everything else down.
In the interests of full disclosure I should warn you that I have the ToolStripPanel and one of the toolstrips added to a baseclass form, and I am trying to add the other toolstrip to a subclass form that inherits from the baseclass form. The ToolStripPanel and ToolStrip in the baseclass form are both declared "Protected Friend", so this should be working. As I mentioned, the subclass form's designer window will allow me to do it (at least, for a time).
If anyone can help me get this working or at least shed some light on why it isn't, I would be extremely grateful.
I created a custom ToolStripPanel so that I could overload the LayoutEngine;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
  class CustomToolStripPanel : ToolStripPanel
  {
    private LayoutEngine _layoutEngine;
    public override LayoutEngine LayoutEngine
    {
      get
      {
        if (_layoutEngine == null) _layoutEngine = new CustomLayoutEngine();
        return _layoutEngine;
      }
    }
    public override Size GetPreferredSize(Size proposedSize)
    {
      Size size = base.GetPreferredSize(proposedSize);
      foreach(Control control in Controls)
      {
        int newHeight = control.Height + control.Margin.Vertical + Padding.Vertical;
        if (newHeight > size.Height) size.Height = newHeight;
      }
      return size;
    }
  }
}
Then the custom LayoutEngine lays out the ToolStrips;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
  class CustomLayoutEngine : LayoutEngine
  {
    public override bool Layout(object container, LayoutEventArgs layoutEventArgs)
    {
      Control parent = container as Control;
      Rectangle parentDisplayRectangle = parent.DisplayRectangle;
      Control [] source = new Control[parent.Controls.Count];
      parent.Controls.CopyTo(source, 0);
      Point nextControlLocation = parentDisplayRectangle.Location;
      foreach (Control c in source)
      {
        if (!c.Visible) continue;
        nextControlLocation.Offset(c.Margin.Left, c.Margin.Top);
        c.Location = nextControlLocation;
        if (c.AutoSize)
        {
          c.Size = c.GetPreferredSize(parentDisplayRectangle.Size);
        }
        nextControlLocation.Y = parentDisplayRectangle.Y;
        nextControlLocation.X += c.Width + c.Margin.Right + parent.Padding.Horizontal;
      }
      return false;
    }
  }
}
One thing that took a while is that changing the location / size of one ToolStrip item will cause the layout to re-fire, with the controls reordered. So I take a copy of the controls before the layout loop. And you cant use AddRange(...) to add items to the Custom Panel for some reason - need to Add(...) them one at a time.
hope that helps (it's based on MSDN LayoutEngine Example, fixed for ToolStripPanels)
Wyzfen
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With