SandDock for WPF User Guide

Getting Started

Back to Table of Contents

A Typical Layout

You are using SandDock because your application, like most, needs organising into separate windows. Ideally the user will be able to reposition these windows into a layout they are comfortable with. There are many different types of layout that can be accomplished with SandDock but they mostly revolve around having one central area (considered the work area) and several other tool windows concerning actions that can be performed on items in the work area.

Tool windows are either located around the edge of the work area or floating elsewhere onscreen, outside the top-level window of your application. Tool windows are held together in groups and when docked to the edge of your work area can be "unpinned", a state where they collapse to occupy very little space at the edge and can be brought onscreen only when needed. The user is free to drag tool windows around to reposition them into hierarchies or different sides of the work area.

You can place any kind of content in the work area of your layout, including SandDock document windows. You can choose whether to display document windows in a tabbed document fashion, like Visual Studio 2005, or in a traditional multiple document interface (MDI) layout. SandDock has its own MDI implementation which includes transition effects, and its tabbed document implementation is second-to-none, including window splitting for arbitrarily complex hierarchies of documents.

Even if you application is simple enough to only require one main piece of user interface with one tool window to help with it, you can choose to use SandDock to present it and the user gains the flexibility to modify the placement of your window so they are comfortable.

SandDock Classes

For your individual windows you will use either the DockableWindow or DocumentWindow class, depending on the desired usage of the window. The classes are virtually identical, varying only in a few cosmetic properties and their default locations. Windows of both types are always (with the exception of MDI scenarios) grouped together with the WindowGroup class for presentation. This allows multiple windows to appear in one group, with tabs to choose between them.

At the root of every SandDock layout is the DockSite class. Everything in your layout is tied to your dock site, and with the exception of floating windows, is presented within its bounds. Your DockSite has a Child property so one element can be presented as the work area, and a SplitContainers collection which represents tool windows docked to the side.

The SplitContainer class is a versatile container that is designed to contain other split containers and window groups. Because it can contain other split containers, it is possible to build up a nested hierarchy of windows. This capability will usually be transparent to the user but it ensures that any window layout they can conceive of is possible.

The choice of element to display as your work area (i.e. the child of your dock site) will vary, but often you will choose to use the DocumentContainer class. Using this will make SandDock aware of your documents, and you can then use either a SplitContainer or an MdiContainer as the child of the DocumentContainer to display either tabbed documents or MDI documents, respectively.

MdiContainer is an ItemsControl-derivative that simply takes DocumentWindow instances as its children, and presents them complete with titlebars, system icons and system buttons like in a normal MDI situation. There are some differences in the way SandDock implements MDI when compared to traditional MDI, brought on by changes in the underlying platform.

Of course, there are more classes than these, but these are the only ones necessary to achieve complex and pleasing layouts.

An Example Layout

It is assumed you will be using XAML to configure your SandDock layouts. Although it is entirely possible to represent them in code, XAML is a logical, structural way of representing a layout. The demonstration application included with the product should be used for reference at this point. You will need to import the SandDock CLR namespace into your XAML page. We usually do so with a simple "sd" prefix for classes.

For this example we will construct a layout with a main work area comprising two documents, with three tool windows - two docked to the right-hand side of the work area and one docked to the bottom. For clarity, each window will simply contain an empty textbox at this point.

	<sd:DockSite>
		<sd:DockSite.SplitContainers>
			<sd:SplitContainer sd:DockSite.Dock="Right">
				<sd:WindowGroup>
					<sd:DockableWindow Title="First Tool Window"><TextBox /></sd:DockableWindow>
				</sd:WindowGroup>
				<sd:WindowGroup>
					<sd:DockableWindow Title="Second Tool Window"><TextBox /></sd:DockableWindow>
				</sd:WindowGroup>
			</sd:SplitContainer>
			<sd:SplitContainer sd:DockSite.Dock="Bottom" sd:DockSite.ContentSize="150">
				<sd:WindowGroup>
					<sd:DockableWindow Title="Third Tool Window"><TextBox /></sd:DockableWindow>
				</sd:WindowGroup>
			</sd:SplitContainer>
		</sd:DockSite.SplitContainers>
		<sd:DocumentContainer>
			<sd:SplitContainer>
				<sd:WindowGroup>
					<sd:DocumentWindow Title="First Document"><TextBox /></sd:DocumentWindow>
					<sd:DocumentWindow Title="Second Document"><TextBox /></sd:DocumentWindow>
				</sd:WindowGroup>
			</sd:SplitContainer>
		</sd:DocumentContainer>
	</sd:DockSite>

Note that we have to use a WindowGroup, even when there is only a single DockableWindow within. For tool windows, tabs are not displayed unless there is more than one window in the group. Simply running this application will allow the user to redock, float and collapse any of the toolwindows, and rearrange the documents.

Normal Window Operations

By default, tool windows can be docked anywhere, floated and collapsed, but not joined to the document area. Also by default, documents can simply be rearranged and split within the document area but cannot be floated or docked. The user accomplishes a change in window position by dragging it by its tab, or dragging a group by its titlebar. While such a docking operation is in progress, hints are displayed to indicate suitable drop locations for the object being dragged. Along with dragging, the user can double-click on a tab or titlebar to cause the object to transition between a floating and fixed state. This is the limit of the docking control the user has by default.

There are a few keyboard shortcuts the user can use, too. While focus is within a window group, pressing Ctrl-PageUp and Ctrl-PageDown moves between the tabs in that group. Pressing Alt-Minus shows the window options (if any), and press Escape restores focus to the document that most recently had the focus. The latter is useful when focus is within a tool window.

The user can close a window at any time, and providing the close is not cancelled programmatically, the only way to bring the window back is to programmatically show it with its Open method. Normally there are entries for each of your windows under your View menu. You can even bind a menu item's command to the DockableWindow.OpenCommand command and set its CommandTarget property so you don't have to write any code.

Responding to Events

SandDock classes raise several events to keep your application in the loop concerning the window operations your user is engaged in. The DockSite class raises events that are typically handled on a layout-wide level, and DockableWindow raises events more usefully handled on a window-specific basis. The following table outlines some of these events because your application will typically need to respond to at least one of them.

DockSite Events
LastActiveWindowChangedThe LastActiveWindow property of your dock site keeps track of the last SandDock window to receive keyboard input focus. This event would normally be used to enable or disable user interface features specific to certain types of window.
LoadWindowRaised when SandDock has encountered a window identifier and is unable to find a matching window in your layout. Your application can then provide it with a window matching the identifier. For more information see the section on layout serialization.
DockingStartedRaised when the user has started dragging a window or group of windows and a docking operation has therefore commenced. Your application can show some helpful hints in the status bar for how to redock windows.
DockingStoppedRaised when the docking operation has stopped.
ShowWindowControlsRaised when a list of window controls needs to be displayed. Your application will normally show a context menu with options such as "Float" and "Dock", for an example see the demonstration application. This event can be raised in response to a right-click on various window parts or clicking the window options button.
DockableWindow Events
ClosingRaised when the window is about to close, whether through the user clicking the close button or a call to its Close method. This event gives the application opportunity to cancel the closure of the window. This is often used to prompt whether to save changes as documents are being closed.
ClosedRaised after a window has been closed.
DockSituationChangedAll windows have a DockSituation property that indicates whether the window is Docked, Floating, a Document or closed (None). This event is raised as the position of the window transitions between these states.

Some events prevent changes to the layout while executing, to stop re-entry and contextual problems from arising. These events are LastActiveWindowChanged, DockingStarted and DockSituationChanged.

Next: Using the Designer