5

Visual Studio 2005 で .net 2.0 を使用しています。フォームの上部に 2 つの異なるツールストリップを追加して、並べて表示しようとしています。Word 2003 のようにして、複数のツールストリップを同じ行に追加し、各ツールストリップに行を割り当てるのではなく、それらを並べて表示できるようにしたいと考えています。

そこで、ToolStripPanel を追加して、フォームの上部にドッキングしました (余分なパネルはすべて必要ないため、ToolStripContainer は使用しませんでした。上部に 1 つだけ必要です)。両方のツールストリップを追加し、それらの Stretch プロパティを False に設定しました。これらをデザイナー ウィンドウに並べて表示することはできますが、実行時に ToolStripPanel はツールストリップを分離し、各ツールストリップに専用の行を提供します。怪我に侮辱を加えるかのように、デバッグを停止してデザイナーに戻ると、デザイナーがツールストリップを独自の行にも移動していることに気付きます! ここで何か間違ったことをしていますか?

私は一日中グーグルをしており、ToolStripPanelRow オブジェクトに関する情報をいくつか見つけましたが、ツールストリップを追加する簡単な方法がわかりません (つまり、ToolStripPanelRow.Controls.Add メソッドなどはありません)。コントロール オブジェクトの配列を返す Controls() プロパティがあり、その配列にアイテムを追加しようとしてもうまくいきませんでした。また、ToolStripPanel.Join メソッドに関するドキュメントもいくつか見つけました。私が何をしたり、どのオプションを試したりしても、常に新しいツールストリップがパネルの上部の独自の行に追加され、他のすべてが押し下げられます。

完全な開示のために、ToolStripPanel とツールストリップの 1 つが基本クラス フォームに追加されており、基本クラス フォームから継承するサブクラス フォームに他のツールストリップを追加しようとしていることを警告しておきます。基本クラス フォームの ToolStripPanel と ToolStrip は両方とも「Protected Friend」として宣言されているため、これは機能するはずです。前述したように、サブクラス フォームのデザイナ ウィンドウを使用すると、(少なくとも、しばらくの間は) それを行うことができます。

誰かが私がこれを機能させるのを手伝ってくれるか、少なくともなぜそうでないのかを明らかにすることができれば、私は非常に感謝しています.

4

3 に答える 3

5

LayoutEngine をオーバーロードできるように、カスタム ToolStripPanel を作成しました。

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;
    }
  }
}

しばらく時間がかかったのは、1 つの ToolStrip アイテムの場所/サイズを変更すると、レイアウトが再起動し、コントロールの順序が変更されることです。そこで、レイアウト ループの前にコントロールのコピーを取得します。また、何らかの理由で AddRange(...) を使用して項目をカスタム パネルに追加することはできません。一度に 1 つずつ Add(...) する必要があります。

お役に立てば幸いです ( MSDN LayoutEngine Exampleに基づいており、ToolStripPanels 用に修正されています)。

ウィズフェン

于 2009-01-22T16:36:55.550 に答える
2

System.Windows.Forms.FlowLayoutPanel は仕事をすることができます。

ToolStrip コントロールを正しい順序で配置するだけです。

于 2009-10-26T06:35:23.713 に答える
1

あなたの場合、独自のカスタム LayoutEngine を必要とするのではなく、ToolStrip の LayoutStyle を ToolStripLayoutStyle.Horizo​​ntalStackWithOverflow に設定するだけで済むと思います。

動的アイテムでレイアウトを処理してオーバーフローをより適切に制御する方法について、同様のトピックで別の質問をしました。

于 2009-03-03T15:14:49.127 に答える