MVVM Support - Building Dock UI

  • 4 minutes to read

This topic covers two ways to building a dock UI using the MVVM design pattern.

  1. Implementing the IMVVMDockingProperties interface - the most common solution; in this approach, each ViewModel should implement the IMVVMDockingProperties interface.
  2. Using the LayoutAdapter - the approach is suitable for advanced tasks, which require dock panels to be placed in positions that cannot be addressed beforehand.

In these two solutions, you assign a collection of ViewModels, which represent dock panels, to the DockLayoutManager.ItemsSource property. For each object in this collection, a dock panel is to be created. The difference between the solutions is in specifying "targets" for dock panels. In DXDocking, "target" is a specific Layout Group or Document Group where the dock panel is placed.

A "target" also defines the type of a created dock panel. If the target refers to a DocumentGroup, the created dock panel will be a DocumentPanel object. If the target is a LayoutGroup, the dock panel will be a LayoutPanel object.

Here are the general customizations applicable in all two approaches.

  • In XAML, create a base layout of Layout Groups and Document Groups into which dock panels will be added. Specify names for these groups.
  • Assign a collection of View Models that represent dock panels to the DockLayoutManager.ItemsSource property. A dock panel will be created for each object in this collection.
  • You can specify how elements of the DockLayoutManager.ItemsSource collection are rendered using the DockLayoutManager.ItemTemplate and DockLayoutManager.ItemTemplateSelector properties.

    <dxdo:DockLayoutManager.ItemTemplate>
        <DataTemplate>
            <dxdo:LayoutPanel Caption="{Binding DisplayName}" />
        </DataTemplate>
    </dxdo:DockLayoutManager.ItemTemplate>
    
  • You can create Styles that target the DocumentPanel and LayoutPanel classes to initialize created dock panels from information provided by View Models.

    <Application.Resources>
        <Style TargetType="{x:Type dxdo:DocumentPanel}">
            <Setter Property="Caption" Value="{Binding Caption}" />
            <Setter Property="CaptionImage" Value="{Binding Glyph}" />
        </Style>
    </Application.Resources>
    
  • To initialize contents of panels, you can define DataTemplates that target dock panel View Models.

    <Application.Resources>
        <DataTemplate DataType="{x:Type local:PanelViewModel}">
            <Grid>
                <Button Content="{Binding Glyph}"/>
            </Grid>
        </DataTemplate>
    </Application.Resources>
    
  • To properly serialize/deserialize the DockLayoutManager layout, bind the BaseLayoutItem.BindableName property to a corresponding property in the panel's View Model.

Implementing the IMVVMDockingProperties interface

In this approach, the View Models must implement the IMVVMDockingProperties interface, which is defined as follows:

namespace DevExpress.Xpf.Docking {
    public interface IMVVMDockingProperties {
        string TargetName { get; set; } //Specifies the name of a target Layout Group or Document Group
    }
}

The TargetName property should return the name of the target Layout Group/Document Group where the created dock panel is to be placed.

A complete example demonstrating the use of the IMVVMDockingProperties interface can be found at: How to build dock UI according to MVVM pattern using IMVVMDockingProperties interface.

Using LayoutAdapter

With this approach, the View Models (for dock panels) can be any object descendants.

Using the LayoutAdapter is appropriate for tasks that require additional customizations. For instance, in some cases, you may not be able to identify a target Layout Group/Document Group for a created dock panel beforehand (e.g. , if the target Layout Group/Document Group does not currently exist). In this case, you need to create the target Group before adding panels to it. The LayoutAdapter class provides a solution to these and other issues that require additional actions to be performed prior to dock panel lay-outing.

The following are steps needed for using the LayoutAdapter.

  1. Create a LayoutAdapter class, which is an object that implements the ILayoutAdapter interface.

    namespace DevExpress.Xpf.Docking
        public interface ILayoutAdapter {
            string Resolve(DockLayoutManager owner, object item);
        }
    }
    

    The Resolve method should return the name of a "target" Layout Group/Document Group for a specific dock panel (passed as the item parameter). When implementing the Resolve method you are able to perform any action prior to returning a target name.

  2. Assign a LayoutAdapter instance to the MVVMHelper.LayoutAdapter attached property on the DockLayoutManager.

See the following topic for an example demonstrating this approach: How to build dock UI according to MVVM pattern using LayoutAdapter.

See Also