SandDock User Guide

Layout Systems

Back to Table of Contents

This tutorial introduces the concept of layout systems and how they're used in SandDock. With this knowledge you can take full control of the way your windows are docked.

How SandDock Works

On the face of it, SandDock appears to have two components that make it work. Firstly you have DockContainers, the controls responsible for holding your DockControls when they are docked and when they are floating. Secondly you have the DockControls themselves, which have text, images and controls within them.

However there is a lot more to SandDock than just this. Because it is possible to configure hierarchies of virtually limitless complexity, there is a whole structure of "layout systems" that operates between DockContainers and DockControls. Normally SandDock isolates these layout systems with great designer support and easy programmatic methods but they are always there, and they are the core of how SandDock works.

Layout Systems exist in hierarchies that reflect the hierarchy of docked controls within a container. There are two types of layout system: SplitLayoutSystems and ControlLayoutSystems.

Split Layout Systems

Split layout systems host other layout systems, and display splitters between them so the user can resize them. Every DockContainer has a split layout system at its root, exposed with its LayoutSystem property. Split layout systems split their child layout systems either vertically or horizontally, and can contain both ControlLayoutSystems and other SplitLayoutSystems.

Control Layout Systems

These are where your DockControls are eventually displayed. Control layout systems have no child layout systems, instead they have child controls. They display a titlebar with buttons, a tabstrip with tabs to choose between available controls and the selected control in their client area.

Most of the user interaction is performed via control layout systems - the only user interaction performed with split layout systems is resizing other layout systems via the splitters.

A special case is DocumentLayoutSystems - these inherit from ControlLayoutSystem and change the behaviour and appearance slightly, but are essentially just the same as ControlLayoutSystems and can be treated so. They display tabs along the top with scrolling, and have no titlebar. They are used in place of ControlLayoutSystem when tabbed document display is required.

Case Study

Let's take the DockContainer shown on the right. This has a layout containing six DockControls, and is slightly more complex than what you would normally see because we want to demonstrate a good hierarchy of layout systems.

Starting off, the DockContainer has its root SplitLayoutSystem, configured with horizontal splitting. This contains two child layout systems, which we'll call Omega and Theta. Omega is on top, and is a ControlLayoutSystem. It contains two controls - Solution Explorer and Class View. Theta is another SplitLayoutSystem, but this time is vertically split.

Theta contains two child layout systems, Delta and Sigma. They are both ControlLayoutSystems. Delta contains the Properties and Dynamic Help DockControls and Sigma contains the Index DockControl. Together the layout systems take charge of laying out their child layout systems and controls proportionally and in a manner the user expects. The ControlLayoutSystems themselves take charge of actually positioning the DockControls.

A good way to visualise the structure behind a layout system is to use the layout persistance methods built in to SandDock. These take an entire SandDock layout and turn it in to XML so it can be reloaded later. To get a string representing your current layout, use the SandDockManager's GetLayout method. Let's take a look at the segment of XML generated for the DockContainer on the right:

<Container Size="254, 495">
  <SplitLayoutSystem SplitMode="Horizontal">
    <ControlLayoutSystem Collapsed="False" Controls="2">
      <Controls>
        <Control Guid="cb07b654-2f5d-4001-b45e-31605760b352" />
        <Control Guid="5e2a8ad8-2e66-48da-912d-1e4ecf0f3106" />
      </Controls>
    </ControlLayoutSystem>
    <SplitLayoutSystem SplitMode="Vertical">
      <ControlLayoutSystem Collapsed="False" Controls="2">
        <Controls>
          <Control Guid="3b9be0fe-6bb7-4341-bf8a-14ef3af1a9b6" />
          <Control Guid="10704056-5361-428a-af0a-e774ec004250" />
        </Controls>
      </ControlLayoutSystem>
      <ControlLayoutSystem Collapsed="False" Controls="1">
        <Controls>
          <Control Guid="a464b2d9-4ebe-432e-a9b9-96ec0a76abe6" />
        </Controls>
      </ControlLayoutSystem>
    </SplitLayoutSystem>
  </SplitLayoutSystem>
</Container>

We have removed some attributes for clarity. The best way to become more confident with layout systems is to try creating some, putting them together then assigning the toplevel split layout system to a DockContainer. All being well, your layout will then be shown and the user is free to interact with it.

The constructors on SplitLayoutSystem and ControlLayoutSystem provide access to all commonly-used functionality. If you design a form that uses SandDock and take a look at the designer-generated code, you will see that the designer code assembles the entire layout system hierarchy in one line of code and assigns it to the LayoutSystem property of each DockContainer.

Back to Table of Contents