title: How do I automatically load a layout into my AvalonDock instance?
body: <p>I have integrated AvalonDock 2.0 into my application. I've bound the document and anchor-able sources to my view-model which are rendered with the proper user controls via <code>DataTemplate</code>s.</p>
  
  <p>I can load and save layouts with the <code>XmlLayoutSerializer</code>. I need to support loading predefined layouts on demand (via <code>Button</code>s and <code>ICommand</code>s). That works as well.</p>
  
  <p>The thing I can't get working is loading a serialized layout automatically when the <code>DockingManager</code> is done loading the view-models and their views (user controls).</p>
  
  <p>I've tried loading my layout on <code>DockingManager.DataContextChanged</code> but I think it fires too early because the layout loads with the documents in the hidden section and duplicate documents in the visible sections. The rendered panes do not reflect the loaded layout and when the layout is saved again the duplicates are accumulated in the hidden section.    </p>
  
  <pre><code>&lt;ad:DockingManager Name="DockingManager"
                     DataContext="{Binding Project}"
                     DataContextChanged="DockingManager_OnDataContextChanged"
                     ActiveContent="{Binding Active}"
                     AnchorablesSource="{Binding Anchorables}"
                     DocumentsSource="{Binding Documents}"&gt;
      &lt;ad:DockingManager.Theme&gt;
          &lt;ad:AeroTheme/&gt;
      &lt;/ad:DockingManager.Theme&gt;
  
      &lt;ad:DockingManager.LayoutItemTemplateSelector&gt;
          &lt;views:PanesTemplateSelector&gt;
              &lt;views:PanesTemplateSelector.ChartTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;views:Chart/&gt;
                  &lt;/DataTemplate&gt;
              &lt;/views:PanesTemplateSelector.ChartTemplate&gt;
              &lt;views:PanesTemplateSelector.WorkspaceTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;Views:Workspace/&gt;
                  &lt;/DataTemplate&gt;
              &lt;/views:PanesTemplateSelector.WorkspaceTemplate&gt;
              ...
          &lt;/views:PanesTemplateSelector&gt;
      &lt;/ad:DockingManager.LayoutItemTemplateSelector&gt;
  
      &lt;ad:DockingManager.LayoutItemContainerStyle&gt;
          &lt;Style TargetType="{x:Type ad:LayoutItem}"&gt;
              &lt;Setter Property="Title" Value="{Binding Model.DisplayText}"/&gt;
              &lt;Setter Property="ContentId" Value="{Binding Model.ContentId}"/&gt;
          &lt;/Style&gt;
      &lt;/ad:DockingManager.LayoutItemContainerStyle&gt;
  
      &lt;ad:LayoutRoot&gt;
          &lt;!--&lt;ad:LayoutPanel&gt;
              &lt;ad:LayoutDocumentPane/&gt;
              &lt;ad:LayoutAnchorablePane/&gt;
          &lt;/ad:LayoutPanel&gt;--&gt;
      &lt;/ad:LayoutRoot&gt;
  &lt;/ad:DockingManager&gt;
  </code></pre>
  
  <p>... and the code-behind ...   </p>
  
  <pre><code>private void SaveLayout() {
      if (this.DataContext == null)
          return;
      var xmlLayoutSerializer = new XmlLayoutSerializer(this.DockingManager);
      var stringBuilder = new StringBuilder();
      using (var textWriter = new StringWriter(stringBuilder))
          xmlLayoutSerializer.Serialize(textWriter);
      var serialized = stringBuilder.ToString();
      (this.DataContext as dynamic).XmlSerializedAndEscapedLayout = HttpUtility.HtmlEncode(serialized);
  }
  private void LoadLayout()
  {
      if (DataContext == null)
          return;
      var encoded = (DataContext as dynamic).XmlSerializedAndEscapedLayout;
      var window = Window.GetWindow(this);
      window.Closing += (sender, args) =&gt; SaveLayout();
      if (String.IsNullOrWhiteSpace(encoded))
          return;
      var serialized = HttpUtility.HtmlDecode(encoded);
      var xmlLayoutSerializer = new XmlLayoutSerializer(DockingManager);
      using (var stringReader = new StringReader(serialized))
          xmlLayoutSerializer.Deserialize(stringReader);
  }
  private void DockingManager_OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  {
      if (e.NewValue != null) // A type check here would be best, I know.
          LoadLayout();
  }
  </code></pre>
  
  <p>... And the view-model ...</p>
  
  <pre><code>public class ProjectViewModel
  {
      public IModel Model { get; private set; }
      public String SerializedLayout { get; set; }
      public ViewModelBase Active { get; set; }
      private readonly ObservableCollection&lt;ViewModelBase&gt; documents;
      public ReadOnlyObservableCollection&lt;ViewModelBase&gt; Documents { get; private set; }
      private readonly ObservableCollection&lt;ViewModelBase&gt; anchorables;
      public ReadOnlyObservableCollection&lt;ViewModelBase&gt; Anchorables { get; private set; }
  
      public ProjectViewModel(String filePath, String serializedLayout)
      {
          SerializedLayout = serializedLayout;
          using (var fileStream = new FileStream(filePath, FileMode.Open))
          {
              IModelRepository modelRepository = Ioc.DependencyInjectionContainer.DefaultContainer.Resolve&lt;IModelRepository&gt;();
              Model = modelRepository.Load(fileStream);
          }
          documents = new ObservableCollection&lt;ViewModelBase&gt;();
          anchorables = new ObservableCollection&lt;ViewModelBase&gt;();
          documents.Add(new Workspace());
          anchorables.Add(new RiskLimitsViewModel(Model.RiskLimits));
          ...
          Documents = new ReadOnlyObservableCollection&lt;ViewModelBase&gt;(documents);
          Anchorables = new ReadOnlyObservableCollection&lt;ViewModelBase&gt;(anchorables);
      }
  }
  </code></pre>
  
  <p>Any insight would be greatly appreciated. Thanks!</p>