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