In This Article

MVVM Features

The Docking & MDI product has been designed to support the popular MVVM pattern. The DockSite control's item container generation features and infrastructure are similar to a standard ItemsControl, but geared towards the generation of docking windows.

Tip

Many of the concepts below are implemented in the MVVM-related samples in the Sample Browser, so be sure to examine those samples.

Specifying Document and Tool Items

The DockSite includes several properties and methods that mimic the design of the native ItemsControl. Using these properties and methods, the DockSite can be bound to a collection of view-models for documents and/or tool windows.

Document Windows

Document windows can be defined by binding the DockSite.DocumentItemsSource property to a collection of items, such as view-models. The items will be wrapped in an instance of DocumentWindow, which is the container used to present the item.

A Style can be applied to the generated DocumentWindow instances by using the DockSite.DocumentItemContainerStyle or DocumentItemContainerStyleSelector properties. Alternatively, an implicit Style for the DocumentWindow type can be defined and placed in the Application.Resources. The Style can be used to bind various properties of the DocumentWindow to the item.

The DataTemplate used by the DocumentWindow instances to present the associated item can be specified using the DockSite.DocumentItemTemplate or DocumentItemTemplateSelector properties. Alternatively, an implicit DataTemplate for the item's type can be defined and placed in the Application.Resources.

Tool Windows

Tool windows can be defined by binding the DockSite.ToolItemsSource property to a collection of items, such as view-models. The items will be wrapped in an instance of ToolWindow, which is the container used to present the item.

A Style can be applied to the generated ToolWindow instances by using the DockSite.ToolItemContainerStyle or ToolItemContainerStyleSelector properties. Alternatively, an implicit Style for the ToolWindow type can be defined and placed in the Application.Resources. The Style can be used to bind various properties of the ToolWindow to the item.

The DataTemplate used by the ToolWindow instances to present the associated item can be specified using the DockSite.ToolItemTemplate or ToolItemTemplateSelector properties. Alternatively, an implicit DataTemplate for the item's type can be defined and placed in the Application.Resources.

Container Customization

The DockSite includes several virtual methods that can be overridden to customize the containers created based on the bound items. These methods mimic the native ItemsControl and includes ClearContainerForItemOverride, GetContainerForItemOverride, IsItemItsOwnContainerOverride, and PrepareContainerForItemOverride. Each of these methods works like its ItemsControl counterpart, with one exception. Each method includes an additional parameter that specifies whether the container is for a document or tool item.

The PrepareContainerForItemOverride method override could be used to bind your view model's properties to the containing docking window's related properties. The ClearContainerForItemOverride method override would clear those bindings. You don't need to override these methods if you are setting up your bindings in a Style instead that gets used by DocumentItemContainerStyle, ToolItemContainerStyle, etc.

Content and Template

As with a standard ItemsControl bound to a collection of view model items, each item will be assigned to the Content property of the generated container docking window.

These view model items require that a content template be specified to properly render their data. As mentioned above, the DocumentItemTemplate, DocumentItemTemplateSelector, ToolItemTemplate, and ToolItemTemplateSelector properties can be used to designate the DataTemplate to use for each item.

Styling the Document and Tool Windows

Custom styles can easily be applied to the DocumentWindow and/or ToolWindow containers created for the bound items. The DocumentItemContainerStyle, DocumentItemContainerStyleSelector, ToolItemContainerStyle, or ToolItemContainerStyleSelector properties can be used to apply a custom Style. Alternatively, an implicit Style for the DocumentWindow and/or ToolWindow types can be defined. The Style can be used to bind various properties of the DocumentWindow and/or ToolWindow to the item.

These styles pulled from our MVVM samples in the Sample Browser show how you can bind various view model properties to the docking windows. The resulting DocumentWindowStyle and ToolWindowStyle properties could then be set to the DockSite.DocumentItemContainerStyle and ToolItemContainerStyle properties respectively:

xmlns:common="clr-namespace:ActiproSoftware.ProductSamples.DockingSamples.Common"
xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking"
...

<common:ToolItemDockSideConverter x:Key="ToolItemDockSideConverter" />
<common:ToolItemStateConverter x:Key="ToolItemStateConverter" />

<Style x:Key="DockingWindowStyle" TargetType="docking:DockingWindow">
    <Setter Property="Description" Value="{Binding Path=Description, Mode=TwoWay}" />
    <Setter Property="ImageSource" Value="{Binding Path=ImageSource, Mode=TwoWay}" />
    <Setter Property="IsActive" Value="{Binding Path=IsActive, Mode=TwoWay}" />
    <Setter Property="IsOpen" Value="{Binding Path=IsOpen, Mode=TwoWay}" />
    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
    <Setter Property="SerializationId" Value="{Binding Path=SerializationId, Mode=TwoWay}" />
    <Setter Property="Title" Value="{Binding Path=Title, Mode=TwoWay}" />
    <Setter Property="WindowGroupName" Value="{Binding Path=WindowGroupName, Mode=TwoWay}" />
</Style>

<Style x:Key="DocumentWindowStyle" TargetType="docking:DocumentWindow" BasedOn="{StaticResource DockingWindowStyle}">
    <Setter Property="FileName" Value="{Binding Path=FileName, Mode=TwoWay}" />
    <Setter Property="IsReadOnly" Value="{Binding Path=IsReadOnly, Mode=TwoWay}" />
</Style>

<Style x:Key="ToolWindowStyle" TargetType="docking:ToolWindow" BasedOn="{StaticResource DockingWindowStyle}">
    <Setter Property="DefaultDockSide" Value="{Binding Path=DefaultDockSide, Mode=TwoWay, Converter={StaticResource ToolItemDockSideConverter}}" />
    <Setter Property="State" Value="{Binding Path=State, Mode=TwoWay, Converter={StaticResource ToolItemStateConverter}}" />
</Style>

Layout Serialization Support

If you plan on serializing your layout between application execution sessions, you must assign your docking windows a unique Name or SerializationId. It is recommended that you use the SerializationId property since unlike the Name property, it can be bound easier and allows any character to be used in the value.

Opening and Positioning the Docking Windows

The DocumentWindow and/or ToolWindow containers created for the bound items will initially be closed and must be opened to appear in the visible layout.

Numerous bindable properties are available on DockingWindow for determining the state and position of docking windows, along with whether they are open and active. For instance, the State property can be set to designate which state the window should open in. This property must remain Document for any DocumentWindow. To open a docking window and add it to the layout, set its IsOpen property to true. To open a docking window (if it isn't already open) and ensure its selected and focused, set its IsActive property to true. This can be done instead of setting IsOpen. Finally, to make sure an already-open docking window's tab is selected, set its IsSelected property to true.

When a docking window is opened via its IsOpen or IsActive properties, it will open in a default location. There are numerous properties and events available that allow you to customize this default location prior to opening the docking window. Some examples are ToolWindow.DefaultDockSide, DockingWindow.WindowGroupName, DockSite.WindowDefaultLocationRequested, etc.

If you prefer to open, activate, dock, etc. a docking window in code-behind instead, this can be easily accomplished by adding a handler for the DockSite.WindowRegistered event. This event is fired once per DocumentWindow and/or ToolWindow when it is initially registered with the DockSite.

The following code shows an example of a WindowRegistered handler:

dockSite.WindowRegistered += this.OnDockSiteWindowRegistered;

// ...

/// <summary>
/// Handles the <c>WindowRegistered</c> event of the <c>DockSite</c> control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="DockingWindowEventArgs"/> instance containing the event data.</param>
private void OnDockSiteWindowRegistered(object sender, DockingWindowEventArgs e) {
	DockSite dockSite = sender as DockSite;
	if (dockSite == null)
		return;

	// Ensure the DockingWindow exists and is generated for an item
	DockingWindow dockingWindow = e.Window;
	if (dockingWindow == null || !dockingWindow.IsContainerForItem)
		return;

	// Open the DockingWindow, if it's not already open
	if (!dockingWindow.IsOpen) {
		// ** Open window in desired location here
	}
}

Item Containers

The DockingWindow.IsContainerForItem property returns true when a docking window is a generated container for an item in the DockSite.DocumentItemsSource or DockSite.ToolItemsSource collections.

The ContainerFromItem method can be used to retrieve the DocumentWindow or ToolWindow associated with a given item. If the type of the item is known, then the ContainerFromDocumentItem or ContainerFromToolItem methods can be used instead.

Item Container Unregistration Triggering Items Source Update

The DockSite.CanUpdateItemsSourceOnUnregister property indicates whether to watch the WindowUnregistered event for an item container DockingWindow to be unregistered. If that property is true, the dock site will try to automatically remove the related item from the appropriate DockSite.DocumentItemsSource or DockSite.ToolItemsSource collection.

The functionality will only succeed if the ItemsSource is an IList that is not read-only or fixed size.

In scenarios where the above conditions are not met, it is up to you to watch the WindowUnregistered event and remove the related item from its items source.

Troubleshooting

See the Troubleshooting topic for more information, with some specific details on configuring data contexts properly.