Попытка добавить ToolStrip в ToolStripPanel рядом с существующим ToolStrip

Я использую .net 2.0 с Visual Studio 2005 и пытаюсь добавить две разные панели инструментов в верхнюю часть формы, чтобы они отображались рядом. Я хочу, чтобы это было похоже на Word 2003, где вы можете добавить несколько полос инструментов в одну и ту же строку и сделать так, чтобы они отображались в соответствии друг с другом, а не выделять строку для каждой панели инструментов.

Поэтому я добавил ToolStripPanel и прикрепил его к верхней части формы (я не использовал ToolStripContainer, потому что мне не нужны все дополнительные панели; мне нужна только верхняя). Я добавил обе панели инструментов и установил для их свойств Stretch значение False. Я могу сделать так, чтобы они отображались в окне дизайнера рядом, но во время выполнения ToolStripPanel разделяет панели инструментов и дает каждой панели инструментов собственную выделенную строку. Как будто чтобы добавить оскорбление к травме, когда я прекращаю отладку и возвращаюсь к дизайнеру, я обнаруживаю, что дизайнер также перемещает панели инструментов в свою собственную строку! Я делаю что-то не так здесь?

Я весь день гуглил и нашел некоторую информацию об объекте ToolStripPanelRow, но я не вижу простого способа добавить к нему панели инструментов (т.е. у него нет метода ToolStripPanelRow.Controls.Add или чего-то подобного), все у него есть свойство Controls(), которое возвращает массив объектов управления, и мне не очень повезло, пытаясь добавить элементы в этот массив. Я также нашел некоторую документацию по методу ToolStripPanel.Join, который звучит так, как будто он должен работать, поэтому я попробовал все 3 перегрузки, но они не работают так, как рекламируется. Независимо от того, что я делаю или какие варианты я пробую, он всегда добавляет новую панель инструментов в верхнюю часть панели в отдельной строке и сдвигает все остальное вниз.

В интересах полного раскрытия я должен предупредить вас, что у меня есть ToolStripPanel и одна из полос инструментов, добавленных в форму базового класса, и я пытаюсь добавить другую полосу инструментов в форму подкласса, которая наследуется от формы базового класса. ToolStripPanel и ToolStrip в форме базового класса объявлены как «Защищенный друг», поэтому это должно работать. Как я уже упоминал, окно дизайнера формы подкласса позволит мне это сделать (по крайней мере, на время).

Если кто-нибудь может помочь мне заставить это работать или, по крайней мере, пролить свет на то, почему это не так, я был бы очень благодарен.


person Patrick    schedule 31.12.2008    source источник


Ответы (3)


Я создал пользовательскую панель ToolStripPanel, чтобы перегрузить 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;
    }
  }
}

Затем пользовательский LayoutEngine размещает 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;
    }
  }
}

Одна вещь, которая заняла некоторое время, заключается в том, что изменение местоположения/размера одного элемента ToolStrip приведет к повторному запуску макета с изменением порядка элементов управления. Поэтому я беру копию элементов управления перед циклом компоновки. И по какой-то причине вы не можете использовать AddRange(...) для добавления элементов на пользовательскую панель - нужно добавлять(...) их по одному.

надеюсь, что это поможет (он основан на Пример MSDN LayoutEngine, исправлено для ToolStripPanels)

Вызфен

person Wyzfen    schedule 22.01.2009
comment
Спасибо за ответ! У меня не было возможности попробовать это, потому что мы решили в конце концов не делать параллельные панели инструментов, но все равно спасибо за публикацию вашего ответа. Я буду иметь это в виду на случай, если мы передумаем. - person Patrick; 23.01.2009

System.Windows.Forms.FlowLayoutPanel может выполнить эту работу.

Просто поместите в него элементы управления ToolStrip в правильном порядке.

person Libor    schedule 26.10.2009
comment
Спасибо за ответ! Попробую, если появится снова. - person Patrick; 04.12.2009

Я думаю, что в вашем случае вы можете просто установить LayoutStyle в вашем ToolStrip на ToolStripLayoutStyle.HorizontalStackWithOverflow, а не использовать свой собственный LayoutEngine.

Я задал другой вопрос по аналогичной теме о том, как обрабатывать макет с динамическими элементами, чтобы лучше контролировать переполнение.

person Jeff Moser    schedule 03.03.2009
comment
Спасибо за ответ; Я больше спрашивал о макете нескольких ToolStrips в одной и той же ToolStripPanel, чем о макете ToolStripItems в ToolStrip (который всегда хорошо работал для меня). - person Patrick; 05.03.2009