Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MultisplitContainer - A FlowlayoutPanel Providing Sizeable Contents

0.00/5 (No votes)
29 Oct 2009 1  
A FlowlayoutPanel providing sizeable contents

Introduction

Sometimes, more or less often, you need to display many controls, e.g. to edit DataRecords with many fields. And you want to give the user the opportunity to resize those editing-controls, depending on whether there is much content to display or little.
You can use SplitContainer to implement that, but SplitContainer only makes two controls sizeable. To get many editing-controls sizeable, you may use many SplitContainers, and nest them into each other. But that leads to a complex structure of controls, and especially changes in GUI-Design can become difficult.

The MultiSplitContainer

You can put all editing-controls into, and each will be sizeable. Of course, you can disable sizeability for some controls, e.g. labels, DateTimePickers and stuff.
In SingleColumnOrRow-Mode Multisplitter layouts, all editing-controls like Dockstyle.Top/Bottom, except (optional) one control with Dockstyle.Fill. This is a behaviour similar to a SplitContainer, but with more Panels.

Another Mode

When SingleColumnOrRow-Mode is off, Multisplitter behaves as a FlowLayoutPanel with sizeable editing-controls.
Multisplitter only supports FlowDirection TopDown or LeftToRight (no BottomUp/RightToLeft).
In TopDown-mode, you additionally can resize the "Expansion", that means: the width of all editing-controls. This comes up as a kind of column-width for the vertical arranged controls.
(Hmm. Not easy to explain, but in action it's easy to use, please try it out.) 

Points of Interest

Splitbars

There is none. The Layout respects the Margin-Property of the editing-controls, and in the space between two controls, the MouseMove-Event reaches the MulitSplitContainer. At that point, it detects the nearby editing-controls, and sets its cursor to HSplit (vertical sizement) or VSplit (horizontal sizement).

Overridden OnLayout-Method

MultisplitContainer inherits from FlowlayoutPanel. In SingleColumnOrRow-Mode it modifies the widths/heights of the editing-controls, to create a docking-like layout. With SingleColumnOrRow.Off the Layout is completely done by the base-class.

IExtenderProvider-Property "IsFilling"

FlowlayoutPanel already implements the IExtenderProvider-Interface, which gives the power to add virtual "Properties" to its contained controls. Although those Properties are implemented in the MulitsplitContainer, they are displayed in Designer as Properties of the contained controls.
I hid the overcome "FlowBreak"-Extender-Property and added an "IsFilling"-Property, so the user can set one of the editing-controls as Filling-Control.
Now, when the user sizes up a control, the Filling-Control shrinks and vice-versa. (like SplitContainer-Behaviour: left panel grows - right panel shrinks).

Ownerdrawing

Thus always two Panels are changing. In SplitContainer it's self-evident, which, but with many "SplitterPanels" in Multisplitcontainer the user cannot see directly, which is the other Panel that will shrink when he enlarges one. So I implemented a little Ownerdrawing to markup the two controls while resizing. 

IExtenderProvider-Property "SizeDynamic"

Disabling sizeability is simply done by setting the controls Minimum/Maximum-Sizes to the value of the current size. Since that's not very comfortable to input in Designer, I added the Extender-Property "SizeDynamic" to the controls, which sets those Values.

No Docking

Since the editing-controls are not really docked, you can drag them easily to (or from) other panels. In a real docking-scenario, you must undock them before you can do so.

Using the Code

Compile project and drag a MultisplitContainer on Form. Drag some editing-controls on it, Textboxes (MultiLine on or off), Comboboxes, Labels (Autosize on or off).

Play in Designer with editing-control-Properties: Margin, IsFilling, SizeDynamic
play in Designer with MultisplitContainer-Properties: TopDown, Expansion, SingleColumnOrRow, AutoScroll, AutoSize, Dock.

Run project and test the resizing-behaviour.

Take a Look

Ãhm, I must admit: The sample-app isn't a real beauty.

MultisplitContainer.gif

But it shows some features:

The Panel on Top has FlowDirection.LeftToRight (MultisplitContainer.TopDown=False), which is useful to display one-line-controls, like Textboxes with Multiline.Off, Comboboxes, DateTimePickers. The Multisplitter is docked.Top with AutoSize.True. The controls are automatically layouted in 3 lines, and the MultisplitContainer will shrink its Height when the form enlarges its width, so that 2 lines of controls are sufficient. Usual FlowlayoutPanel-behaviour.
But MultisplitContainer allows the user to resize the textboxes, and the flowlayout will follow.

Below on the left, there is MultisplitContainer.TopDown=True. In this mode, you can also display multi-line-controls, and resize them in vertical direction. You can also size them in horizontal direction, but if you do so, every control grows/shrinks - that is a kind of column-with the vertical Flow-Layout. I called that Property "Expansion", because when TopDown=False it works accordingly.

On the right, there is MultisplitContainer.SingleColumnOrRow set to True. And there is set one editing-control as "FillingControl".
Now it behaves very similar to SplitContainer. All Space is filled, and if you resize a control, the FillingControl will compensate the growing/shrinking, so that all controls stay in view without using scrollbars.

That's the fourth opportunity: If no FillingControl is set, the controls can grow greater than the MultisplitContainer, and the vertical scrollbar will appear.

Still Something To Do

As you see, nearly every editing-control needs a Caption-Label to make sense. In the Sample-App, I helped myself by placing Caption-Label and editing-control together on a little panel, the label docked left, the editing-control docked fill. That still is a little circumstantial to figure out. One should create a "CaptionPanel", which would provide a caption and can take an editing-control, and it would layout the editing-control automatically centered in the remaining space.
But that may be stuff for another article.

The control is not programmed out perfectly (it's new!). Maybe some features could be implemented more comfortably (e.g. locking sizeability in both directions only can be done by setting MaximumSize by hand). But I hope that it gives you some ideas to implement dynamic layout, and it shows some techniques (as IExtenderProvider-Properties, userdefined Layout, Ownerdrawing) to make it better or to create an own MultisplitContainer.

And I think, it's quite stable, because I didn't grasp very deep into the controls' behaviour - most of the work is done by the good old FlowlayoutPanel.

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