Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FlowLayoutPanel autowrapping doesn't work with autosize

.NET Framework / C# / Windows Forms

I'd like the FlowLayoutPanel to automatically adjust its width or height depending on number of controls inside of it. It also should change the number of columns/rows if there is not enough space (wrap its content). The problem is that if I set autosize then the flowlayoutpanel doesn't wrap controls I insert. Which solution is the best?

Thanks!

like image 548
Yegor Avatar asked Sep 24 '09 11:09

Yegor


4 Answers

I know this is an old thread but if anyone else wonders on here then here's the solution I produced - set autosize to true on the panel and call this extension method from the flow panel's Resize event:

public static void ReOrganise(this FlowLayoutPanel panel)
{
    var width = 0;
    Control prevChildCtrl = null;

    panel.SuspendLayout();

    //Clear flow breaks
    foreach (Control childCtrl in panel.Controls)
    {
        panel.SetFlowBreak(childCtrl, false);
    }

    foreach (Control childCtrl in panel.Controls)
    {
        width = width + childCtrl.Width;

        if(width > panel.Width && prevChildCtrl != null)
        {
            panel.SetFlowBreak(prevChildCtrl, true);
            width = childCtrl.Width;
        }

        prevChildCtrl = childCtrl;
    }

    panel.ResumeLayout();
}
like image 78
DavidWainwright Avatar answered Oct 26 '22 13:10

DavidWainwright


Set the FlowLayoutPanel's MaximumSize to the width you want it to wrap at. Set WrapContents = true.

like image 26
Oliver Bock Avatar answered Nov 06 '22 08:11

Oliver Bock


Have you tried using the TableLayoutPanel? It's very useful for placing controls within cells.

like image 1
Icono123 Avatar answered Nov 06 '22 09:11

Icono123


There is no such thing like impossible in software development. Impossible just takes longer.

I've investigated the problem. If there is really need for Flow Layout, it can be done with a bit of work. Since FlowLayoutPanel lays out the controls without particularly thinking about the number of rows/columns, but rather on cumulative width/height, you may need to keep track of how many controls you've already added. First of all, set the autosize to false, then hook your own size management logic to the ControlAdded/ControlRemoved events. The idea is to set the width and height of the panel in such a way, that you'll get your desired number of 'columns' there

Dirty proof of concept:

private void flowLayoutPanel1_ControlAdded(object sender, ControlEventArgs e)
    {
        int count = this.flowLayoutPanel1.Controls.Count;
        if (count % 4 == 0)
        {
            this.flowLayoutPanel1.Height = this.flowLayoutPanel1.Height + 70;
        }
    }

if the panel has initially width for 4 controls, it will generate row for new ones. ControlRemoved handler should check the same and decrease the panel height, or get all contained controls and place them again. You should think about it, it may not be the kind of thing you want. It depends on the usage scenarios. Will all the controls be of the same size? If not, you'd need more complicated logic.

But really, think about table layout - you can wrap it in a helper class or derive new control from it, where you'd resolve all the control placing logic. FlowLayout makes it easy to add and remove controls, but then the size management code goes in. TableLayout gives you a good mechanism for rows and columns, managing width and height is easier, but you'd need more code to change the placement of all controls if you want to remove one from the form dynamically.

like image 1
usualexpat Avatar answered Nov 06 '22 09:11

usualexpat