Simple AvalonDock application with only LayoutDocumentPane.
XAML:
<Window x:Name="MainWindow1" x:Class="AvalonTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
Title="MainWindow" Height="350" Width="525" Loaded="MainWindow1_Loaded">
<Grid Name="MainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0" Grid.Column="0">
<Button Content="New Tab" Margin="10,0,0,0" Click="NewTabClick"/>
<Button Content="Save layout" Margin="10,0,0,0" Click="Button_Click"/>
</ToolBar>
<xcad:DockingManager x:Name="dockManager" Grid.Row="1">
<xcad:LayoutRoot x:Name="_layoutRoot">
<xcad:LayoutPanel Orientation="Horizontal" x:Name="_layoutPanel">
<xcad:LayoutDocumentPane x:Name="workSpace">
<xcad:LayoutDocument ContentId="dummy" Title="Dummy" >
<Button x:Name="dummyButton" Content="Dummy Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</xcad:LayoutDocument>
</xcad:LayoutDocumentPane>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
</Window>
Code:
using System;
using System.IO;
using System.Windows;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;
namespace AvalonTest2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NewTabClick(object sender, RoutedEventArgs e)
{
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
workSpace.Children.Add(ld);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var layoutSerial = new XmlLayoutSerializer(dockManager);
layoutSerial.Serialize("layout.xml");
}
private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{
if (File.Exists("layout.xml"))
{
// var serializer = new XmlLayoutSerializer(dockManager);
// serializer.Deserialize("layout.xml");
}
}
}
}
I press "New tab" button and everything is fine: new tab appears.
I restart the program, save layout ("Save layout" button), close program and remove comments on Deserialize lines.
I start the program and on pressing "New tab", no tabs appears. I'd look inside LayoutDocumentPane (workSpace), "Children" property is filled with new Documents.
What's wrong?
Unfortunately, the (de-)serializing functionality is implemented not very nice in the AvalonDock
suite.
On deserializing, a completely new LayoutRoot
object will be created. You define in XAML a LayoutDocumentPane
with name workSpace
and add the newly created LayoutDocument
into this pane. But, after deserialization, this LayoutDocumentPane
does not belong to the layout anymore - it has been removed; a new LayoutDocumentPane
has been created instead.
Therefore you cannot see any LayoutDocument
views added into the workSpace
container.
Don't reference the instance of your LayoutDocumentPane
by name, but rather find it dynamically instead. You have to change your code to something like:
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
LayoutDocumentPane documentPane = this.dockManager.Layout.Descendents().OfType<LayoutDocumentPane>().SingleOrDefault();
if (documentPane != null)
{
documentPane.Children.Add(ld);
}