Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Windows Forms controls - controlling the z-order

Talking to other developers and hanging around newsgroups and forums I noticed quite a few people have problems arranging controls on a windows form in design time. A typical problem is the overlapping of docked controls. For example, put a Panel and a MenuStrip on a blank form (in that exact order) and set Panel's Dock property to Fill [MenuStrip should already be docked to top]. This results in Panel's top area being hidden behind the MenuStrip:

 

Why's that? The way how controls on a form are docked is determined by the z-order [how controls are layered along the form's Z-axis - depth]. The control's z-order is determined by its position in container's Controls collection, with the first control in the collection being at the front (top layer) and the last at the back.

Thus, in the previous example, the form's Controls collection order is: [0: MenuStrip, 1: Panel], and since higher-layered controls can overlap those behind them, the Panel, having Dock set to Fill, can take all the space it needs, without MenuStrip blocking its way.

Now, as you've already guessed, we need to change control's z-order to make things look right. If Panel was put in front of MenuStrip, MenuStrip would still be visible (it's docked to Top) and Panel would only occupy the remaining of form's space.

To fix this at design time, we have a few options:

  • Right-click on the Panel and select "Bring to Front". This will change Panel's position in form's Controls collection to 0, making it the top of z-order. Similarly, you could right-click on MenuStrip and choose "Send to Back".
  • Select the Panel and choose "Format | Order | Bring to Front" from Visual Studio's menu. There are also two icons on the Layout toolbar that do the same thing.

  • Visual Studio 2005 also includes a very useful tool window called Document Outline (menu: View | Other Windows | Document Outline, shortcut: Ctrl+Alt+T), allowing you to rearrange controls by simple drag and drop operations, moving it among different containers and changing their z-order:

At run time, when adding controls dynamically, you can change control's z-order programmatically: every control, derived from Control class, has BringToFront() and SendToBack() methods:

Panel panel = new Panel();
Controls.Add(panel);
panel.BringToFront();

There's many ways you can control the layout of your forms and controls, changing z-order is just one of them. Setting your controls' margins, padding, anchoring and docking properties properly will help you create powerful layouts, which will automatically adjust to various screen resolutions and form's sizes, without the need of additional coding for adapting user controls when user resizes the form.

[Update: images above were copied directly to WLW and published using FTP Image publishing feature. Issues encountered were image blurring - see above - and numerous errors/republish attempts to upload all images successfully. Also, pictures were "taken" on Windows Vista July CTP]