2013-03-12 61 views
6

我正尝试使用自己的布局引擎创建自定义面板控件。 我需要添加到我的面板的下方添加,并采取全宽​​(-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%宽度),但当控件的高度大于我的容器高度我得到水平滚动条,但添加一些控件更多的滚动条被删除。 adding components

同样的事情发生时,我想调整我的容器: resizing container

这可怎么固定?我只需要移除水平滚动条。

当然,所有的改进都是欢迎的。

我不想使用表格布局或流式布局,因为这一个给我什么时候我需要的。

我需要一个简单的容器,从上到下对所有子控件进行排序并水平拉伸它们,因此它们需要尽可能多的宽度,因此不需要容器水平滚动条。

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

因此他们将调整水平

+0

但如果它是固定的,你不能把新闻bottons永远... O_O – MayogaX 2013-03-12 11:43:17

+0

@MayogaX - 我知道:)我只是想表达我的观点。我将有自定义控件而不是按钮。我的观点是要展示我的面板如何运作。大多数情况下,我会在那里有2-3个控件,但是当用户添加新控件时,我想避免当水平滚动条可见时出现的情况。调整我的应用程序的同样的情况。我将在那里持有最多5-6个控件。以上只是一个演示,以显示不需要的行为。 – Misiu 2013-03-12 11:48:35

+2

您正试图解决Winforms设计师在LayoutEngine类中小心翼翼的问题。像这样的布局*双稳态*。试图解决它的最典型的结果是在水平滚动条闪烁的情况下陷入无限循环。你有点注定要重塑班级,并最终以同样的方式去做。 – 2013-03-12 11:50:02

回答

3

这里是一个工作的例子,不幸的是,不使用你的布局引擎类:

+0

布局引擎只是一个很好的选择,但我在滚动条上遇到了问题。如果你的解决方案解决了这个问题,那么它对我来说是完美的:) – Misiu 2013-03-13 08:10:18

+1

我检查了你的解决方案,作品像一个魅力:)唯一应该添加的是'O​​nControlRemoved'的重载来调用'LayoutControls'来移除滚动条。 – Misiu 2013-03-13 08:32:39

-1

你可以在你喜欢的按钮设置AnchorProperty。它仅仅依赖于OnControlAdded和OnControlRemoved方法,以及固定和设置AutoScrollMinSize属性还专门确保永远不会出现水平滚动条:

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 2013-03-12 11:46:21