Pergunta

Eu estou usando .net 2.0 com Visual Studio 2005 e eu estou tentando adicionar duas toolstrips diferentes para a parte superior do formulário de tal forma que eles aparecem lado a lado. Quero que seja como Word 2003, onde você pode adicionar várias toolstrips a mesma linha e tê-los mostrar-se em linha com o outro, em vez de dedicar uma linha para cada toolstrip.

Então eu adicionei um ToolStripPanel e ancorado-lo para a parte superior do formulário (eu não usar um ToolStripContainer porque eu não preciso de todos os painéis extras, eu só preciso a um no topo). Eu adicionei ambos toolstrips e definir suas propriedades esticar para False. Eu posso levá-los a aparecer na janela de designer de side-by-side, mas em tempo de execução do ToolStripPanel separa os toolstrips e dá a cada toolstrip sua própria linha dedicada. Como se para adicionar insulto à injúria, quando eu parar a depuração e voltar para o designer, eu estou achando que o designer está se movendo os toolstrips a sua própria linha também! Estou fazendo algo errado aqui?

I foram pesquisando todo o dia e encontrei algumas informações sobre um objeto ToolStripPanelRow, mas eu não vejo uma maneira fácil de adicionar toolstrips a ele (ou seja, ele não tem um método ToolStripPanelRow.Controls.Add ou qualquer coisa assim ), tudo o que tem é uma Controls () propriedade que retorna uma matriz de objetos de controle, e eu não tive muita sorte tentando adicionar itens a essa matriz. Eu também encontrei alguma documentação sobre o método ToolStripPanel.Join, que soa como ele deve fazer o trabalho, então eu tentei todos os 3 sobrecargas, mas eles não funcionam como anunciado. Não importa o que eu faço ou que opções eu tento, ele sempre adiciona o novo toolstrip ao topo do painel em sua própria linha e empurra tudo para baixo.

No interesse da divulgação completa eu deveria avisá-lo que eu tenho a ToolStripPanel e um dos toolstrips adicionados a uma forma baseclass, e eu estou tentando adicionar outro toolstrip a uma forma subclasse que herda a forma baseclass. A ToolStripPanel e ToolStrip na forma baseclass são ambos declararam "Amigo Protegido", por isso deve estar funcionando. Como eu mencionei, a janela de designer do formulário subclasse vai permitir-me para fazê-lo (pelo menos, por um tempo).

Se alguém pode me ajudar a obter esse trabalho ou pelo menos lançar alguma luz sobre por que não é, eu ficaria muito grato.

Foi útil?

Solução

Eu criei um ToolStripPanel personalizado para que eu poderia sobrecarregar o 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;
    }
  }
}

Em seguida, a LayoutEngine costume estabelece as 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;
    }
  }
}

Uma coisa que levou um tempo é que a mudança do local / tamanho de um item ToolStrip fará com que o layout para re-fogo, com os controles reordenadas. Então eu levo uma cópia dos controles antes do loop layout. E você não pode usar AddRange (...) para adicionar itens ao painel personalizado por algum motivo -. Necessidade de adicionar (...)-los um de cada vez

esperança que ajuda (ele é baseado em MSDN LayoutEngine Exemplo , fixada para ToolStripPanels)

Wyzfen

Outras dicas

System.Windows.Forms.FlowLayoutPanel pode fazer o trabalho.

Basta colocar os controles ToolStrip nele com ordem correta.

Eu acho que no seu caso, você pode ir longe com apenas definir o LayoutStyle em seu ToolStrip para ToolStripLayoutStyle.HorizontalStackWithOverflow em vez de necessidade seu próprio LayoutEngine personalizado.

Eu pedi um diferente questão sobre um tema semelhante sobre como lidar com layout com itens dinâmicos para ter um melhor controle do transbordamento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top