FlowLayoutPanel - Automatic Width for controls?

45,017

Solution 1

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.

Solution 2

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

Solution 3

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

Solution 4

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.

EDIT - In response to @UsamaAziz comment.

To ensure the controls which are hidden beyond the bottom of the panel are accessible, set the "AutoScroll" property of the panel to True. This will add a vertical scrollbar to the panel when it is required.

Job Done.

Solution 5

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.

Share:
45,017
MilMike
Author by

MilMike

&lt;?php echo "hi"; ?&gt; Hi, my name is Mike. I love to code. Started to code over 20 years ago. I feel at home using a bride spectrum of technologies. Currently I work full time as a web developer in Germany working on PHP/JS projects, but I also developed desktop applications for Windows. Most of the time I work as a backend developer but I also love to work with frontend. If you want to know more about me, just go to my small website or follow me on instagra: My Website Instagram

Updated on July 09, 2022

Comments

  • MilMike
    MilMike almost 2 years

    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.