AvalonDock 2.0 and MVVM

Background

When I was writing an application, I came to the conclusion that a flexible GUI Layout that enables the user to rearrange the windows to fit their needs would be the best option. I wanted an interface that is as flexible as Visual Studio itself when it comes to window positioning.

Docking Libraries

Back in the days, I've already used a commercial solution, but that was years ago and I didn't have a license for a current version. That's why I took a look at our all favourite site and so came to find AvalonDock.

AvalonDock

AvalonDock is a Wpf Docking Library that provides your windows app with docking windows just like Visual Studio. The library has a lot going for it: it's available as a nuget package, totally free and it comes with MVVM support (which I deeply care about), at least the codeplex page claims it does.

Getting AvalonDock

There a two options to get AvalonDock, either grab it from the codeplex site under downloads or get it via nuget. While I prefer nuget, this time you need to take care to select the correct package, as there is also a pay-only version available as well as an older, out of date version. It's simply named 'AvalonDock', take a look at the screenshot below:

While the library does what I want, I found it's documentation quite lacking - the tutorials, except for one, are hopelessly outdated - they refer to the version 1.3 while the current version (as of this writing) is 2.0. As almost none of the classes, properties or methods are the same, they are more misleading than do any good.

Considering that the last comment that asks for an update of the documentation was written in 2012 and has gone unanswered, I wouldn't hold my breath for an update anytime soon.

So heading back to our favorite site, search reveals promising questions but lacking answers: consisting of a 'let me google that for you' link, followed by a link to an article about the version 1.3 or another one with answers that link to the same outdated tutorial and one that links to the codeplex documentation page, which got us started hunting for information in the first place, all apparently posted by someone point-hungry that skipped reading the whole question.

Finding an example app

After some looking around I found an example app back on the CodePlex site - it's not under downloads, there you'll only find the library and some themes - but under source code and you can get it when clicking the Download Button.

Now we're off to a good start - we can see some of the properties in use, even in a somewhat MVVMish use.

Putting it to use

After studying the MVVM example, I knew how to bind the DocumentManager against a Document Collection, and wanted it to use it in a way that allows me to just update the properties of our viewmodels and have the view reflect those changes and vice-versa. That would come in handy for opening and closing windows and updating the title and so on.

First of all, I wanted to use the IsChecked property of the menu item to open and close the DockWindow and so on, as shown in the screenshot below.

AvalonDock using Mvvm Bindings to close and openwindows

The following xaml code snippet shows how I wired up the View to ViewModel binding with a style:

<Window ...
  xmlns:dock="http://schemas.xceed.com/wpf/xaml/avalondock"
  xmlns:dockctrl="clr-namespace:Xceed.Wpf.AvalonDock.Controls;assembly=Xceed.Wpf.AvalonDock"
  >
  ...
  <dock:DockingManager Grid.Row="1"
                        DataContext="{Binding DockManagerViewModel}"
                        DocumentsSource="{Binding Documents}" >

    <dock:DockingManager.LayoutItemContainerStyle>
      <!-- you can add additional bindings from the layoutitem to the DockWindowViewModel -->
      &ltStyle TargetType="{x:Type dockctrl:LayoutItem}">
        <Setter Property="Title" Value="{Binding Model.Title}" />
        <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
        <Setter Property="CanClose" Value="{Binding Model.CanClose}" />
      </Style>
    </dock:DockingManager.LayoutItemContainerStyle>

  </dock:DockingManager>
</Window>

As figuring out how to use the MVVM support was harder than expected and in case anyone else needs to do that, I've uploaded a complete example app to github that should get you started.

Take care,
Martin

References