Applications often have their own view models that expose domain specific properties. Dock’s MVVM helpers let you derive from its Document
, Tool
or Dock
classes so that your models participate in the docking system. This guide explains how to combine your own view models with the Dock view models.
Create a custom view model
Derive from one of the MVVM base classes and add your own properties. The following example extends Document
:
using Dock.Model.Mvvm.Controls;
public class FileViewModel : Document
{
private string _path = string.Empty;
public string Path
{
get => _path;
set => SetProperty(ref _path, value);
}
}
Use the view model in a factory
Instantiate your custom view models when building the layout.
public class DockFactory : Factory
{
public override IRootDock CreateLayout()
{
var file = new FileViewModel { Id = "File1", Title = "File" };
var root = CreateRootDock();
root.VisibleDockables = CreateList<IDockable>(
new DocumentDock
{
VisibleDockables = CreateList<IDockable>(file),
ActiveDockable = file
});
root.DefaultDockable = root.VisibleDockables[0];
return root;
}
}
Initialize the layout
In your application, create the factory, build the layout and call InitLayout
.
var factory = new DockFactory();
var layout = factory.CreateLayout();
factory.InitLayout(layout);
Dock.Layout = layout;
Your custom view models now behave like any other Dock documents or tools while still exposing your application specific state.
ContextLocator
instead of inheritanceIf you prefer to keep your view models independent of Dock you can resolve them through
ContextLocator
. Create plain Document
or Tool
instances and register the view models
by Id
when initializing the layout.
public class FileInfoViewModel
{
public string Path { get; set; } = string.Empty;
}
public class DockFactory : Factory
{
public override IRootDock CreateLayout()
{
var document = new Document { Id = "File1", Title = "File" };
var root = CreateRootDock();
root.VisibleDockables = CreateList<IDockable>(
new DocumentDock
{
VisibleDockables = CreateList<IDockable>(document),
ActiveDockable = document
});
root.DefaultDockable = root.VisibleDockables[0];
return root;
}
public override void InitLayout(IDockable layout)
{
ContextLocator = new Dictionary<string, Func<object?>>
{
["File1"] = () => new FileInfoViewModel { Path = "file.txt" }
};
base.InitLayout(layout);
}
}
InitLayout
assigns a new FileInfoViewModel
to the document’s Context
property so your
view can bind to it.
Context
manuallyWhen creating layouts entirely in code you can also bypass ContextLocator
and assign the
context directly:
var document = new Document
{
Id = "File1",
Title = "File",
Context = new FileInfoViewModel { Path = "file.txt" }
};
This technique avoids both inheritance and locator dictionaries but does not work with serialized layouts because the context instance is not recreated automatically.
For further customization options see the MVVM guide and the Advanced guide.