Click here to Skip to main content
15,922,015 members
Articles / Programming Languages / C#
Article

Bringing Back FlowLayout to WinForms Controls

Rate me:
Please Sign up or sign in to vote.
3.45/5 (10 votes)
8 Oct 20041 min read 118.9K   1.4K   31   18
This article describes how to create a Panel that allows FlowLayout positioning for WinForms.

Sample Image - FlowLayoutPanel.jpg

Introduction

With the next Visual Studio being in Beta 2 and the FlowLayout supposedly making its comeback in said revision, this could very well be a day late and a dollar short, but I had need of it and thought I would share it anyway. The FlowLayout option for laying out your controls has been missing from .NET WinForms for sometime now. While many of us don't mind absolute positioning, it can get to be a bear (or at the very least annoying) when you want to add controls dynamically but don't want to worry about System.Drawing.Points or .Top and .Left properties.

Background

I'm currently implementing a thumbnail view and was anguished over the fact that there was no FlowLayout option for WinForms, and having Googled for FlowLayout controls and seeing a remarkable dearth of them, I decided to write my own and share it for general consumption.

Since I've posted this, I've enhanced it a little to include a LayoutStyle property that takes an enum for LayoutStyles.FlowLayout or LayoutStyles.GridLayout.

Usage

The FlowLayoutPanel is a small application with a custom control (FlowLayoutPanel.cs) that extends System.Windows.Forms.Panel and overrides:

C#
protected override void OnLayout(LayoutEventArgs levent)

to handle FlowLayout behavior for the Panel.

It's straightforward and simple, with all the real work being done in the method above (code below). The download contains a solution from Visual Studio .NET 2003 that bundles an example application and the FlowLayoutPanel. Barring the addition of a LayoutStyle property, there is no significant difference in the usage between this and a standard Panel, except, of course, if the LayoutStyle property is set to LayoutStyles.FlowLayout, then adding a control via this.Controls.Add(someControl) or dragging and dropping in design mode positions the control automatically using FlowLayout characteristics.

C#
protected override void OnLayout(LayoutEventArgs levent)
{
    if (this.LayoutStyle == LayoutStyles.FlowLayout) 
    {
      int nextTop = 0, nextLeft = 0;
      int maxHeight = 0, maxWidth = 0;
      int ParentWidth;
      if (this.Parent != null)
      {
          ParentWidth = this.Parent.Width;
      }
      else
      {
          ParentWidth = this.Width;
      }
      foreach(Control myControl in this.Controls)
      {
          myControl.Top = nextTop;
          myControl.Left = nextLeft;
          if (myControl.Height > maxHeight)
          {
              maxHeight = myControl.Height;
          }
          if (myControl.Width > maxWidth)
          {
              maxWidth = myControl.Width;
          }
          if ((nextLeft + myControl.Width + maxWidth) >= ParentWidth)
          {
              nextTop += maxHeight;
              nextLeft = 0;
          }
          else
          {
              nextLeft += myControl.Width;
          }
      } 
    this.AutoScrollPosition = new System.Drawing.Point(0,0);
    base.OnLayout (levent);
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
President Premier Programming Services
United States United States
Matt Dockins is the President of Premier Programming Services, offering custom programming solutions for the Sage SalesLogix Business Partner and Sage SalesLogix Client as well as general programming services.

Premier Programming Services is a fully licensed Sage SalesLogix Development Partner, a VineyardSoft KnowledgeSync partner, and Certified Microsoft ISV.

http://www.premierprogrammingservices.com




Comments and Discussions

 
GeneralAdd this snippet to enable smooth scrolling Pin
Malcolm Hall26-Jun-08 5:34
Malcolm Hall26-Jun-08 5:34 
QuestionWill this work with Compact Framework? Pin
Member 2073130-Jan-07 5:03
Member 2073130-Jan-07 5:03 
QuestionCan we Center Align of controls in flowlayout? Pin
shhameed27-Jul-05 1:37
shhameed27-Jul-05 1:37 
QuestionFix for ordering newly added controls? Pin
Carl Mercier20-Apr-05 9:40
Carl Mercier20-Apr-05 9:40 
AnswerRe: Fix for ordering newly added controls? Pin
Anonymous21-Apr-05 5:50
Anonymous21-Apr-05 5:50 
GeneralA few added properties Pin
gregoftheweb19-Jan-05 11:11
gregoftheweb19-Jan-05 11:11 
GeneralDocking and Anchoring Pin
Duray AKAR14-Dec-04 6:08
sussDuray AKAR14-Dec-04 6:08 
GeneralSome problems and their solutions Pin
Marc Clifton7-Nov-04 3:35
mvaMarc Clifton7-Nov-04 3:35 
A few things I had to fix to actually use the control:

I noticed that when resizing the demo form, it determines whether the wrapped control can be redrawn on the previous row based on the size of the last control drawn, rather than the size of the actual next control.

I'm not sure why the code checks to see if a parent to the FlowLayoutPanel exists and uses its width instead. This causes problems in calculating whether a control can fit, both when the FlowLayoutPanel is displaying a scrollbar and in cases when the panel isn't taking up the whole width of the parent control.

ClientSize.Width should really be used instead of just the Control's width, as this gives the true usable width rather than including scrollbar width and borders.

The GridLayout option isn't implemented, so I removed it.

The comparison to >= parentWidth should be >, as equality would still allow the child control to fit (I think!).

maxHeight needs to be reset to 0 after wrapping to the next row. Otherwise, it'll just keep setting the row height to the largest control already encountered in the other rows. Same with maxWidth if doing a top-down or bottom-up flow.

I also noticed that the call to AutoScrollPosition=(0,0) needs to be done first, otherwise placing additional child controls with a non-(0,0) scroll position results in some odd placement behavior.

I also added the ability to specify flow direction and a "WrapContents" flag to my version. If you're interested in it, send me an email.

Marc

MyXaml
Advanced Unit Testing
GeneralRe: Some problems and their solutions Pin
Matt Dockins7-Nov-04 16:54
Matt Dockins7-Nov-04 16:54 
GeneralRe: Some problems and their solutions Pin
Carl Mercier20-Apr-05 9:35
Carl Mercier20-Apr-05 9:35 
GeneralRe: Some problems and their solutions Pin
Marc Clifton20-Apr-05 14:49
mvaMarc Clifton20-Apr-05 14:49 
GeneralRe: Some problems and their solutions Pin
Carl Mercier20-Apr-05 14:53
Carl Mercier20-Apr-05 14:53 
GeneralThanks Pin
Steven Campbell29-Oct-04 9:41
Steven Campbell29-Oct-04 9:41 
GeneralRe: Thanks Pin
Carl Mercier20-Apr-05 5:42
Carl Mercier20-Apr-05 5:42 
GeneralRe: Thanks Pin
Carl Mercier20-Apr-05 9:46
Carl Mercier20-Apr-05 9:46 
GeneralLooks good Pin
Marc Clifton8-Oct-04 9:57
mvaMarc Clifton8-Oct-04 9:57 
GeneralRe: Looks good Pin
Matt Dockins8-Oct-04 10:40
Matt Dockins8-Oct-04 10:40 
GeneralRe: Looks good Pin
chadyoshikawa7-Aug-05 6:13
chadyoshikawa7-Aug-05 6:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.