49

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

一个包含 1 个 FlowLayoutPanel 和 3 个按钮的表单:

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

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

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

4

7 回答 7

49

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

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

于 2011-03-22T20:40:22.970 回答
20

这是执行此操作的简单方法。只需绑定您 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();
}
于 2013-03-20T16:27:44.667 回答
10

这里我有我的 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;
                }
            }
        }
    }
}
于 2017-04-12T08:16:56.590 回答
5

这里没有必要FlowLayoutPanel

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

编辑 - 回应@UsamaAziz 评论。

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

任务完成。

于 2018-08-13T14:28:40.947 回答
3

根据MSDNFlowLayoutPanel,以特定方式排列控件:

...对于垂直流向,FlowLayoutPanel 控件根据 column中最宽的子控件计算隐含列的宽度。此列中具有AnchorDock 属性的所有其他控件都对齐或拉伸以适合此隐含列。对于水平流向,该行为以类似的方式起作用。

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

于 2015-09-29T02:22:10.240 回答
2

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

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

或者在属性中设置...

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

于 2012-02-23T03:55:05.947 回答
1

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

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

祝你今天过得愉快。

于 2018-12-05T18:19:24.220 回答