FlowLayoutPanel - Automatic Width for controls?

2019-04-03 01:39发布

is it possible to make the inserted items in FlowLayoutPanel automatic size of the FlowLayoutPanel? Here is an example:

A form with 1 FlowLayoutPanel and 3 buttons inside:

enter image description here

if I resize the form, the controls look like this: they arrange "left to right"

enter image description here

What I want is this: The controls should have the width of the FlowLayoutPanel:

enter image description here

Any Ideas how to do this? I changed the FlowDirection and played with the Anchor property but with no luck.

I could of course Resize the controls in the FlowLayoutPanel_Resize event, but I want to add about 500 usercontrols - I tested it and it is slow.

7条回答
爷的心禁止访问
2楼-- · 2019-04-03 01:48

There is no need for a FlowLayoutPanel here.

You should be able to do what you want with a normal Panel control. Anchor it at all four sides so that it stretches with your form, then add your buttons and set them all to Dock: Top.

Job Done.

查看更多
霸刀☆藐视天下
3楼-- · 2019-04-03 01:49

here I have my StackPanel class:

/// <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楼-- · 2019-04-03 01:52

The FlowLayoutPanel arranges controls in a particular way, according to MSDN:

...for vertical flow directions, the FlowLayoutPanel control calculates the width of an implied column from the widest child control in the column. All other controls in this column with Anchor or Dock properties are aligned or stretched to fit this implied column. The behavior works in a similar way for horizontal flow directions.

Its not ideal, but you can do this natively, as long as one child control is set to the same width as the container, and the rest of the controls are set to Dock.

查看更多
forever°为你锁心
5楼-- · 2019-04-03 01:55

It's simple way to do this. Just bind the SizeChanged evnent of you flowLayoutPannel and resize the containing control. Like:

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();
}
查看更多
做自己的国王
6楼-- · 2019-04-03 01:56

I suggest you using TableLayoutPanel with one column in this case. I have found TableLayoutPanel much more predictable and solid than FlowLayoutPanel.

Another option, if you still want to use FlowLayoutPanel, is to set first control width to desired one, and use Dock = Top for all other controls.

查看更多
放荡不羁爱自由
7楼-- · 2019-04-03 02:03

I Suggest... try playing with the anchors of the buttons... try setting it as

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

or set it in the properties...

and then put it inside a Panel instead of the FlowLayoutPanel... ;)

查看更多
登录 后发表回答