2013-03-12 20 views
6

自分のレイアウトエンジンでカスタムPanelコントロールを作成しようとしています。 私は以下のように、下に追加されるように、私のパネルに追加され、全幅(-padding)を取るためにすべてのコントロールを必要とする: 以下enter image description hereレイアウトエンジンを備えたカスタムパネル

は私のコードです:上記のコード

using System.Drawing; 
using System.Windows.Forms; 
using System.Windows.Forms.Layout; 

namespace VContainer 
{ 
    internal class VerticalFillList : Panel 
    { 
     public VerticalFillList() 
     { 
      AutoScroll = true; 
      MinimumSize = new Size(200, 200); 
      Size = new Size(200, 300); 
      Padding = new Padding(10); 
     } 

     private readonly VerticalFillLayout _layoutEngine = new VerticalFillLayout(); 

     public override LayoutEngine LayoutEngine 
     { 
      get { return _layoutEngine; } 
     } 

     private int _space = 10; 

     public int Space 
     { 
      get { return _space; } 
      set 
      { 
       _space = value; 
       Invalidate(); 
      } 
     } 
    } 

    internal class VerticalFillLayout : LayoutEngine 
    { 
     public override bool Layout(object container, LayoutEventArgs layoutEventArgs) 
     { 
      var parent = container as VerticalFillList; 

      Rectangle parentDisplayRectangle = parent.DisplayRectangle; 
      Point nextControlLocation = parentDisplayRectangle.Location; 

      foreach (Control c in parent.Controls) 
      { 
       if (!c.Visible) 
       { 
        continue; 
       } 

       c.Location = nextControlLocation; 
       c.Width = parentDisplayRectangle.Width; 
       nextControlLocation.Offset(0, c.Height + parent.Space); 
      } 
      return false; 
     } 
    } 
} 

が正常に動作しますただし、コントロールの高さがコンテナの高さよりも大きい場合は、水平スクロールバーが表示されますが、カップルコントロールを追加した後は、正しく追加されます(親の100%幅よりも新しい)より多くのスクロールバーが削除されます。これは resizing container

を固定することができます方法:私は私のコンテナのサイズを変更したいとき adding components

同じことが起こりますか?私はその水平スクロールバーを削除する必要があります。もちろん

すべての改善は、私は必要なときにこの1つは正確に私を与えるようなテーブルレイアウトまたはフローレイアウトを使用したくない歓迎:)

です。

すべての子コントロールを上から下に並べて水平に伸ばして、コンテナの水平スクロールバーを必要としないように幅を広げる単純なコンテナが必要です。

button1.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top; 

だから、彼らはここで

+0

をそれが固定されている場合:これは単にOnControlAddedとOnControlRemoved方法に依存して、具体的には、水平スクロールバーは表示されませんを確認するためにAutoScrollMinSizeプロパティを固定して設定します – MayogaX

+0

@MayogaX - 私はそれを知っている:)私はちょうど私のポイントを示したいと思った。私はボタンの代わりにカスタムコントロールを持っています。私のポイントは、私のパネルがどう動くかを示すことでした。ほとんどの場合、2-3個のコントロールがありますが、ユーザーが新しいコントロールを追加するときは、その水平スクロールバーが表示されている状態を避けたいです。アプリケーションのサイズを変更する場合と同じ状況です。私はそこに最大5-6のコントロールを持っています。上記は、望ましくない動作を示すデモです。 – Misiu

+2

WinFormsのデザイナーがLayoutEngineクラスで慎重に踏み込んだ問題を解決しようとしています。このようなレイアウトは*双安定*です。それに対処しようとする最も典型的な結果は、水平スクロールバーが点滅して無限ループに陥っていることです。あなたはクラスを再考して同じようにやり遂げることになります。 –

答えて

3

が、残念ながら、あなたのレイアウトエンジンクラスを使用していない実施例である水平方向にサイズ変更することがあります:

+0

レイアウトエンジンは私にとってはうまくいくオプションでしたが、スクロールバーに問題がありました。あなたの解決策がその問題を解決すればそれは私にとって完璧です:) – Misiu

+1

あなたのソリューションをチェックしました。魅力的です:)追加する必要があるのは 'OnControlRemoved'のオーバーライドで、' LayoutControls'を呼び出してスクロールバーを削除します。 – Misiu

-1

はあなたのようなあなたのボタンでAnchorPropertyを設定することができます。 O_O ...あなたは永遠にニュースbottonsを置くことはできません

internal class VerticalPanel : Panel { 
    private int space = 10; 

    public int Space { 
    get { return space; } 
    set { 
     space = value; 
     LayoutControls(); 
    } 
    } 

    protected override void OnControlAdded(ControlEventArgs e) { 
    base.OnControlAdded(e); 
    LayoutControls(); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) { 
    base.OnControlRemoved(e); 
    LayoutControls(); 
    } 

    private void LayoutControls() { 
    int height = space; 
    foreach (Control c in base.Controls) { 
     height += c.Height + space; 
    } 
    base.AutoScrollMinSize = new Size(0, height); 

    int top = base.AutoScrollPosition.Y + space; 
    int width = base.ClientSize.Width - (space * 2); 
    foreach (Control c in base.Controls) { 
     c.SetBounds(space, top, width, c.Height); 
     c.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right; 
     top += c.Height + space; 
    } 
    } 
} 
+0

私はレイアウトエンジンがコンテナ内のすべてのコンポーネントの位置を扱うので、ボタンのアンカーは必要ありません。カスタムパネル内のボタンのサイズが正しく調整されています。私がする必要があるのは、水平スクロールバーを削除することです。 – Misiu

関連する問題