I am trying to bind the Width
and Height
properties of the floating (undocked) documents in AvalonDock
. I am using MVVM
pattern.
I want to save the properties (together with the docking state and the position of the window, if undocked) and be able to restore them. Using a XmlLayoutSerializer
is not an option because this requires a reference to the docking manager which is not allowed in the ViewModel.
This is the XAML code:
<avalonDock:DockingManager DocumentsSource="{Binding Files}"
ActiveContent="{Binding ActiveDocument, Mode=TwoWay}">
<avalonDock:DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type avalonDock:LayoutDocumentItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="CanClose" Value="False" />
<Setter Property="CanFloat" Value="True" />
</Style>
</avalonDock:DockingManager.LayoutItemContainerStyle>
<avalonDock:LayoutRoot>
<avalonDock:LayoutPanel>
<avalonDock:LayoutDocumentPane>
</avalonDock:LayoutDocumentPane>
</avalonDock:LayoutPanel>
</avalonDock:LayoutRoot>
The ViewModel:
private ObservableCollection<PaneViewModel> m_readonyFiles;
public ObservableCollection<PaneViewModel> Files
{
get { return m_readonyFiles ?? (m_readonyFiles =
new ObservableCollection<PaneViewModel>()); }
}
private PaneViewModel _activeDocument = null;
public PaneViewModel ActiveDocument
{
get { return _activeDocument; }
set
{
if (_activeDocument != value)
{
_activeDocument = value;
RaisePropertyChanged("ActiveDocument");
}
}
}
I tried to set a binding in the style of LayoutDocumentItem
but the setter never gets called:
<Window.Resources>
<Style TargetType="{x:Type avalonDock:LayoutDocumentItem}">
<Setter Property="Width" Value="{Binding ActiveDocument.CurrentWidth, Mode=TwoWay}"></Setter>
<Setter Property="Height" Value="{Binding ActiveDocument.CurrentHeigth, Mode=TwoWay}"></Setter>
</Style>
</Window.Resources>
How can I save and restore the size and position of the floating documents without violating the MVVM pattern?
Solution Update >>>
I finally solved my problem with an idea from one of the articles @Sheridan linked to in his answer. I created a messenger that handles communication between my ViewModel and the CodeBehind of the View. There I get position and size of the documents and send them back to ViewModel. To restore, I use a ILayoutUpdateStrategy
and in the function AfterInsertDocument
, I restore the states.