I am facing the problem that I cannot open an anchorable of type X after I have loaded my old layout. This happens only when I have closed the anchorable of type X before saving the layout.
Does anyone have a similar problem with AvalonDock? Is this a bug of AvalonDock? After years of debugging, I fear that the binding <Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
doesn't get updated correctly in the view, when changing IsActive
in the ViewModel. AvalonDock should be responsible for this task. But maybe the problem is the loading and saving of the layout?
The code
View
I am loading the saved layout of my anchorables (= tool windows) in the Loaded
Event of my DockingManager
in my View like this (simplified):
string savedLayout = Properties.Settings.Default.Layout;
XmlDocument doc = new XmlDocument();
doc.LoadXml(savedLayout);
// very simplified code. load saved xml layout and add anchorables to the dockmanager
doc.SelectNodes("//LayoutAnchorable").OfType<XmlNode>().ToList().ForEach(anchorable =>
{
this.DockManager.AnchorablesSource.Add(anchorable);
});
I am saving the current layout of my anchorables in the Closing
Event of my MainWindow
in my View like this (simplified):
XmlDocument doc = new XmlDocument();
XmlLayoutSerializer xmlLayoutSerializer = new XmlLayoutSerializer(this.DockManager);
using (MemoryStream stream = new MemoryStream())
{
xmlLayoutSerializer.Serialize(stream);
stream.Seek(0, SeekOrigin.Begin);
doc.Load(stream);
}
// here happens some magic. i think this code is not responsible for my problem
Properties.Settings.Default.Layout = doc.OuterXml;
The ViewModel is bound to the ViewModel in the XAML like this (simplified):
<xcad:DockingManager x:Name="DockManager" AnchorablesSource="{Binding Tools}" Loaded="DockManager_Loaded">
<xcad:DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type dockctrl:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.ContentId}" />
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}" />
<Setter Property="CanClose" Value="{Binding Model.CanClose, Mode=TwoWay}" />
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={StaticResource Bool2vis}, ConverterParameter={x:Static Visibility.Hidden}}"/>
<Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
<Setter Property="IconSource" Value="{Binding Model.IconSource}" />
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}" />
</Style>
</xcad:DockingManager.LayoutItemContainerStyle>
[...]
ViewModel
The anchorable is opened in the ViewModel of the MainWindow. Here is the example code for the messages:
public ObservableCollection<ToolBoxViewModelBase> Tools { get; } = new ObservableCollection<ToolBoxViewModelBase>();
public MainWindowViewModel()
{
// [...]
this.MessagesWindow = new MessagesWindowViewModel();
SimpleIoc.Default.Register<MessagesWindowViewModel>(() => this.MessagesWindow);
this.ShowMessagesWindowCommand = new RelayCommand(() => this.OpenToolBox(this.MessagesWindow));
// [...]
}
public void OpenToolBox<T>(T viewModel) where T : ToolBoxViewModelBase
{
// [...]
viewModel.IsVisible = true;
viewModel.IsActive = true;
// [...]
}
Just let me know if you need more information or wether i have missed to add some code!