【问题标题】:FlowLayoutPanel - Automatic Width for controls?FlowLayoutPanel - 控件的自动宽度?
【发布时间】:2011-03-22 18:01:09
【问题描述】:

是否可以使 FlowLayoutPanel 中插入的项自动调整为 FlowLayoutPanel 的大小?这是一个例子:

一个内部有 1 个 FlowLayoutPanel 和 3 个按钮的表单:

如果我调整表单大小,控件看起来像这样:它们“从左到右”排列

我想要的是:控件应该有 FlowLayoutPanel 的宽度:

任何想法如何做到这一点?我更改了 FlowDirection 并使用 Anchor 属性,但没有运气。

我当然可以在 FlowLayoutPanel_Resize 事件中调整控件的大小,但我想添加大约 500 个用户控件 - 我测试过,它很慢。

【问题讨论】:

  • 是的,调整大小可以正常工作。无论您做什么,都不要添加 500 个控件,否则会很烂。一个表单不应包含超过 50 个控件。
  • 我正在尝试创建某种类似于 Apple Automator 中的“ListView”:bit.ly/fxkMaH
  • 我在您提供的链接中只看到 4 个项目,而不是 500 个。
  • @Justin 截图被简化了。
  • 我只是想指出,对我来说,调整大小可以正常工作。我还在整个地方都使用双缓冲,所以也许这会让它感觉更快(因为它不会闪烁)。但我肯定不会添加 500 个控件……我无法想象这将是多么不可用,可怜的用户。

标签: .net vb.net resize flowlayoutpanel


【解决方案1】:

在这种情况下,我建议您使用带有一列的 TableLayoutPanel。我发现 TableLayoutPanel 比 FlowLayoutPanel 更可预测和更可靠。

如果您仍想使用 FlowLayoutPanel,另一种选择是将第一个控件宽度设置为所需的宽度,并将 Dock = Top 用于所有其他控件。

【讨论】:

  • 但是每次在里面添加控件都得管理表格的行数,对吧?
  • 没有必要。当您添加一个控件时,只需设置 Dock=Top,它的行为将遵循列表中的第一个。您只需确保在 FlowLayoutPanel 的大小发生更改时设置 flayoutpanel.Controls[0].Width=flayoutpanel.Width。
【解决方案2】:

这是一种简单的方法。 只需绑定您 flowLayoutPannel 的 SizeChanged 事件并调整包含控件的大小。 喜欢:

private void myFlowLayoutPannel_SizeChanged(object sender, EventArgs e)
{
    myFlowLayoutPannel.SuspendLayout();
    foreach (Control ctrl in pnSMS.Controls)
    {
        if (ctrl is Button) ctrl.Width = pnSMS.ClientSize.Width;
    }
    myFlowLayoutPannel.ResumeLayout();
}

【讨论】:

  • 这也是我遇到这个问题时的第一个想法,但这不能减慢GUI吗?
  • 超人,它对我来说很好用。我将上述解决方案与此解决方案混合在一起:)
  • 太旧了,但我建议使用FlowLayoutPannelLayout 事件来调整控件的大小。
【解决方案3】:

这里有我的 StackPanel 类:

/// <summary>
/// A stackpanel similar to the Wpf stackpanel.
/// </summary>
public class StackPanel: FlowLayoutPanel
{
    public StackPanel(): base()
    {
        InitializeComponent();
        this.ForceAutoresizeOfControls = true;
    }

    private void InitializeComponent()
    {
        this.SuspendLayout();
        //
        // StackPanel
        //
        this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
        this.WrapContents = false;
        this.ResumeLayout(false);
    }

    /// <summary>
    /// Override it just in order to hide it in design mode.
    /// </summary>
    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new bool WrapContents
    {
        get { return base.WrapContents; }
        set { base.WrapContents = value; }
    }

    /// <summary>
    /// Override it just in order to set its default value.
    /// </summary>
    [DefaultValue(typeof(AutoSizeMode), "GrowAndShrink")]
    public override AutoSizeMode AutoSizeMode
    {
        get { return base.AutoSizeMode; }
        set { base.AutoSizeMode = value; }
    }

    /// <summary>
    /// Get or set a value that when is true forces the resizing of each control.
    /// If this value is false then only control that have AutoSize == true will be resized to
    /// fit the client size of this container.
    /// </summary>
    [DefaultValue(true)]
    public bool ForceAutoresizeOfControls { get; set; }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        this.SuspendLayout();
        switch (FlowDirection)
        {
            case FlowDirection.BottomUp:
            case FlowDirection.TopDown:
                foreach (Control control in this.Controls)
                    if (ForceAutoresizeOfControls || control.AutoSize)
                        control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
                break;
            case FlowDirection.LeftToRight:
            case FlowDirection.RightToLeft:
                foreach (Control control in this.Controls)
                    if (ForceAutoresizeOfControls || control.AutoSize)
                        control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
                break;
            default:
                break;
        }
        this.ResumeLayout();
    }

    protected override void OnLayout(LayoutEventArgs levent)
    {
        base.OnLayout(levent);

        if (levent != null && levent.AffectedControl != null)
        {
            Control control = levent.AffectedControl;
            if (ForceAutoresizeOfControls || control.AutoSize)
            {
                switch (FlowDirection)
                {
                    case FlowDirection.BottomUp:
                    case FlowDirection.TopDown:
                        control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
                        break;
                    case FlowDirection.LeftToRight:
                    case FlowDirection.RightToLeft:
                        control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

【讨论】:

    【解决方案4】:

    这里不需要FlowLayoutPanel

    您应该能够使用普通的Panel 控件做您想做的事情。 将其锚定在所有四个侧面,使其与您的表单一起伸展,然后添加您的按钮并将它们全部设置为 Dock: Top。

    编辑 - 回应 @UsamaAziz 评论。

    要确保隐藏在面板底部之外的控件可以访问,请将面板的“AutoScroll”属性设置为 True。这将在需要时向面板添加一个垂直滚动条。

    工作完成。

    【讨论】:

    • 如果我想在其中添加 100 个控件?我不认为面板可以处理这个问题,因为它没有滚动条。
    • @UsamaAziz 可以。只需将面板的“AutoScroll”属性设置为 True。然后当控件超出面板底部时,会自动添加一个垂直滚动条。
    【解决方案5】:

    FlowLayoutPanel 根据MSDN 以特定方式排列控件:

    ...对于垂直流向,FlowLayoutPanel 控件计算 隐含列的宽度从最宽的子控件中 列。此列中使用 AnchorDock 的所有其他控件 属性被对齐或拉伸以适应这个隐含的列。这 水平流向的行为以类似的方式起作用。

    这并不理想,但您可以在本机执行此操作,只要将一个子控件设置为与容器相同的宽度,并将其余控件设置为 Dock

    【讨论】:

      【解决方案6】:

      我建议...尝试使用按钮的锚点...尝试将其设置为

      Button1.Anchor = (AnchoreStyle.Left or AnchoreStyle.Right)
      

      或 在属性中设置...

      然后将其放入 Panel 而不是 FlowLayoutPanel... ;)

      【讨论】:

      • 同意。但是,Panel 无法正确处理子控件边距。
      【解决方案7】:

      正如其他答案所述,面板本身足以处理您的按钮。对我有用的代码:

      public class ButtonWindow : Panel
      {
          public ButtonWindow()
          {
              Dock = DockStyle.Fill;
              AutoScroll = true;
      
              for (int i = 0; i < 500; i++) 
              {
                 Button button = new Button() { Height = 100, Dock = DockStyle.Top };
                 Controls.Add(button);
              }
          }
      }
      

      祝你有美好的一天。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-17
        • 2013-05-29
        • 2014-03-06
        • 1970-01-01
        • 2022-07-14
        • 2013-07-20
        • 1970-01-01
        相关资源
        最近更新 更多