MVVM Adapter for WPF Docking Manager

This article explains how to adapt the Syncfusion docking manager to an MVVM application. Since our WPF Docking Manager is not an item control, it is not possible to have a traditional item-source binding to a collection of objects in the view model. This can, however, be achieved by creating a wrapper or adapter for the docking manager.

I have used a simple text-reader application to demonstrate this approach. The sample looks like this:

  1. 1. Documents View: The pane that lists all the available documents. The tooltip will display the path of the document.
  2. 2. Properties View: The pane that shows the properties of a document. Our PropertyGrid control is used here.
  3. 3. Document View: The pane that uses the WPF flow-document reader to display the content of a file.
  4. 4. Command View: The view has two commands: Open Document and Exit. Executing an Open Document action will open the Open File Dialog. The document you open will be added to the existing documents list. Other commands like Close Document and New Document can also be implemented the same way.

The project structure looks like this:

Docking Adapter
The adapter is simply a user control that contains our docking manager as its content. The adapter has two properties—ItemsSource and ActiveDocument. Binding a collection of objects to the ItemsSource property will trigger a collection change in which the adapter will create a corresponding framework element (e.g., a Content control) in the docking manager, setting the underlying data context of the control to the business model.

<mvvm:dockingadapter itemssource="{Binding Workspaces}" activedocument="{Binding ActiveDocument,Mode=TwoWay}">
 
</mvvm:dockingadapter>

 

Our text-reader application maintains a collection of workspaces. A workspace can be a normal dock pane or a document pane. The adapter also maintains an interface called IDockElement, which maintains basic attributes needed for every dock element.

(The text-reader application is just for the sample and contains very basic operations. This article and sample intend to showcase the MVVM support for the docking manager.)

The adapter user control also determines the state of the element, whether it should be added to the docking manager as a dock element or document tab.

(The adapter can be further customized to add elements as floating or auto-hidden.)

The docking manager provides an ActiveWindowChanged event. Using this, the ActiveDocument property in the adapter needs to be updated every time focus changes to other panes.

Application structure

The view model has a collection of workspaces that is data-bond to the ItemsSource property of the docking adapter. The adapter transforms the particular view model or business object into a corresponding dock element in the docking manager.

Every dock element we see in the application is a workspace. There are three kinds of workspaces: the All Documents view, the Properties view, and the Document view. The docking adapter hooks up the “active window changed” event of the docking manager; the view model receives the message whenever the active document is changed.

Data Template
Since WPF has an implicit template approach, it is easy for us to apply visuals to the view models. In this application, the data templates are defined in App.xaml with only the DataType attribute mentioned and not key-specified. The WPF template engine will traverse the tree and find the appropriate model type and apply the templates.

            
<application.resources>
            <datatemplate datatype="{x:Type local:Document}">
                <grid>
                    <local:documentview></local:documentview>
                </grid>
            </datatemplate>
            <datatemplate datatype="{x:Type local:DocumentsViewModel}">
                <grid>
                    <local:documentsview></local:documentsview>
                </grid>
            </datatemplate>
            <datatemplate datatype="{x:Type local:PropertiesViewModel}">
                <grid>
                    <local:propertiesview></local:propertiesview>
                </grid>
            </datatemplate>
</application.resources>

 

Following this approach, the docking adapter can also be treated as a normal item control and can be used in any MVVM application.

Sample link

https://github.com/SyncfusionExamples/working-with-wpf-docking-manager-and-mvvm

wpf