Click here to Skip to main content
Click here to Skip to main content

MultisplitContainer - A FlowlayoutPanel Providing Sizeable Contents

, 29 Oct 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mr.PoorEnglish

Germany Germany
No Biography provided

Comments and Discussions

 
QuestionDesign-time error Pinmembertonygluk19-May-12 22:05 
AnswerRe: Design-time error PinmemberMr.PoorEnglish19-May-12 22:23 
GeneralRe: Design-time error Pinmembertonygluk19-May-12 23:13 
GeneralOIC [modified] Pinmemberkonikula6-Jan-10 21:35 
regarding your another autosizing project, I take back my proposition on using FlowLayoutPanel. Yours's pretty more sophisticated. WTF | :WTF: I'll have to dig in this your article deeper. BTW: excellent Cool | :cool:
 
BTW2: this is good candidate to next .NET component, by my anarchist opinion. Rose | [Rose] And next point for you is hand-made implementation of splitter. Really hardcore ideas!
 
BTW3: even if MS doesn't hire you (what stupid option!), you already became my TOP3 designers over world {M.Russinovich, M.Doherty, Mr. BadEnglish}. only sad thing is that I'm loosing my opinion that I'm the best programmer over the world Laugh | :laugh:
 
QUASI-ADVICE: do you remember how ToolTip component behaves when placed on form? In property box for every control on that form, appears property "ToolTip on ToolTip1". That's really thing you can mimic, just using some metadata (or whatever, I don't know). If you think about this, you can implement similar component, containing all settings of each label as properties, and adding "HasLabel", "LabelAlign", "LabelMargin" and "LabelText" properties (and another) to child controls. (Also having some of these properties default in component will make it good). I'm not sure if you can add properties using your main control, or if you'll have to nest some component explicitly, but hopefully you can do that with some such hack. That's my advice on your "There are things to do". Thank you for these adventures. Really really good work! Thumbs Up | :thumbsup: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup:
 
modified on Thursday, January 7, 2010 2:52 AM

GeneralRe: OIC PinmemberMr.PoorEnglish26-Feb-10 0:31 
QuestionVS2005 version or executable file? PinmemberSergei Petrik25-Oct-09 2:10 
AnswerRe: VS2005 version or executable file? PinmemberMr.PoorEnglish29-Oct-09 11:28 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 29 Oct 2009
Article Copyright 2009 by Mr.PoorEnglish
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid