DockableContent.RestoreLayout() question

Nov 24, 2009 at 1:24 AM
Edited Nov 24, 2009 at 1:26 AM

Hello, DockableContent.RestoreLayout() expects an xml element. I have tried sending in several levels of my xml with no results. Does anything look wrong with the code. I've tried sending in the DockableContent, the ResizingPanel and the DockingManager, but the DockableContent never Restores to the correct position. I have gotten DockingManager.RestoreLayout working, but I need to restore the layout of a single DockableContent, not the whole manager. Thanks.

XML LAYOUT SAVE FILE (default.xml)

<?xml version="1.0" encoding="utf-8" ?>
- <DockingManager>
- <ResizingPanel ResizeWidth="*" ResizeHeight="*" EffectiveSize="0,0" Orientation="Horizontal">
  <DocumentPanePlaceHolder />
- <ResizingPanel ResizeWidth="*" ResizeHeight="*" EffectiveSize="472,749.04" Orientation="Vertical">
- <DockablePane ResizeWidth="*" ResizeHeight="*" EffectiveSize="472,749.04" Anchor="Right">
  <DockableContent Name="NewModule" AutoHide="false" />
  </DockablePane>
  </ResizingPanel>
- <ResizingPanel ResizeWidth="*" ResizeHeight="*" EffectiveSize="472,749.04" Orientation="Vertical">
- <DockablePane ResizeWidth="*" ResizeHeight="*" EffectiveSize="472,372.52" Anchor="Right">
  <DockableContent Name="ModuleLauncher" AutoHide="false" />
  </DockablePane>
- <DockablePane ResizeWidth="*" ResizeHeight="*" EffectiveSize="472,372.52" Anchor="Right">
  <DockableContent Name="LayoutsModule" AutoHide="false" />
  </DockablePane>
  </ResizingPanel>
  </ResizingPanel>
  <Hidden />
  <Windows />
  </DockingManager>

C# CODE 

 

 


 

string fileName = "default.xml";
            XmlDocument xmlDoc = new XmlDocument();
            XmlElement element;

            if (File.Exists(fileName))
            {
                xmlDoc.Load(fileName);
                XmlNode node = xmlDoc.SelectSingleNode("//DockingManager");
		//XmlNode node = xmlDoc.SelectSingleNode("//DockableContent[@Name='" + moduleInfo.FullName + "']"); //this got the DockingContent without results		
        //        node = node.ParentNode; //combined with line above, this got the resizingPanel without results

                foreach (DockableContent content in this.manager.DockableContents)	 //manager is type DockingManager and contains all the correct DockableContent
                {
                    if (moduleInfo.FullName == content.Name) //this if statement works and restorelayout is called for the correct content
                    {
                        content.RestoreLayout((XmlElement)node);
                    }
                }
            }
Dec 28, 2009 at 9:03 PM

It seems like there are a ton of questions with very few answers around here.

Jan 8, 2010 at 8:43 PM

Docking manager is not loaded. Are you trying to restore the layout in the form constructor?

Jan 8, 2010 at 9:01 PM

STEP_BY_STEP_HOW_TO

So, in your XAML code, where your docking manager is defined, change:

<ad:DockingManager x:Name="dockManager">

to

<ad:DockingManager x:Name="dockManager" Loaded="DockingManagerControl_Loaded">

Next, add the following method in the C# code behind:

private void DockingManagerControl_Loaded(object sender, RoutedEventArgs e)
{
   if (File.Exists(path))
   {
      FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
      dockManager.RestoreLayout(fs);
      fs.Close();
   }
}

Also, to save the layout, do something similar:

At the top of the aforementioned XAML file, change

<Window x:Class="AvalonDockTest.DemoPane"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
    Title="DemoPane Docking Example" Height="376" Width="600">

to

<Window x:Class="AvalonDockTest.DemoPane"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
    Title="DemoPane Docking Example" Height="376" Width="600" Closing="Window_Closing">

Once again, add the following method in the C# code:

private void Window_Closing(object sender, CancelEventArgs e)
{
   dockManager.SaveLayout(path);
}

Jan 11, 2010 at 7:53 PM
Edited Jan 11, 2010 at 7:57 PM

Hello, thanks for your attempts to solve my problem :) but I am trying to restore the layout of a single DockableContent, not an entire DockingManager. I have successfully implemented the DockingManager Save and Restore Layouts.

This is the function I'm trying to make work.

File:

DockableContent

Class:

public class DockableContent : ManagedContent

 Function:

public virtual void RestoreLayout(XmlElement contentElement); //Note it takes an element from the file, not the whole file
Thanks :)

Feb 18, 2010 at 3:03 PM

mackgammeter - I used your code and on open it makes the whole screen blank.  

my XML code that it is trying to load is

 

<DockingManager>
- <ResizingPanel ResizeWidth="*" ResizeHeight="*" EffectiveSize="0,0" Orientation="Horizontal">
- <ResizingPanel ResizeWidth="*" ResizeHeight="*" EffectiveSize="1011,853" Orientation="Horizontal">
- <DockablePane ResizeWidth="325" ResizeHeight="*" EffectiveSize="325,853" Anchor="Left">
  <DockableContent Name="contentSetup" AutoHide="false" /> 
  </DockablePane>
  <DockablePane ResizeWidth="*" ResizeHeight="*" EffectiveSize="682,853" Anchor="Left" /> 
  </ResizingPanel>
  </ResizingPanel>
  <Hidden /> 
  <Windows /> 
  </DockingManager>

and my c# code is 

 

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            string filename = "C:\\VDS\\layout.xml";
            try
            {
                dockManager.SaveLayout(filename);
            }
            catch
            {
                System.IO.Directory.CreateDirectory("C:\\VDS");
                dockManager.SaveLayout(filename);
            }
        }
        private void dockManager_Loaded(object sender, RoutedEventArgs e)
        {
            dockManager.Anchor(paneSetup, AvalonDock.AnchorStyle.Left);
            
            string path = "C:\\VDS\\layout.xml"; 
            if (File.Exists(path))
            {
                FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                dockManager.RestoreLayout(fs);
                fs.Close();
            }
        }

 

 

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            string filename = "C:\\VDS\\layout.xml";
            try
            {
                dockManager.SaveLayout(filename);
            }
            catch
            {
                System.IO.Directory.CreateDirectory("C:\\VDS");
                dockManager.SaveLayout(filename);
            }
        }

        private void dockManager_Loaded(object sender, RoutedEventArgs e)
        {
            dockManager.Anchor(paneSetup, AvalonDock.AnchorStyle.Left);
            

            string path = "C:\\VDS\\layout.xml"; 

            if (File.Exists(path))
            {
                FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                dockManager.RestoreLayout(fs);
                fs.Close();
            }
        }

 

any ideas?

 

 

 

Feb 22, 2010 at 12:55 PM

It seems as though if you don't have a document viewer in your layout that the restore doesn't work as expected.  Once I put a document viewer in everything started working.  Thanks for the code.

Mar 3, 2010 at 4:51 PM

I tried this but i still have an issue when i dock panels inside another panels (Not resizing panels only).

 

I receive the an InvalidOperationException ("The enumerator is not valid because the collection changed.") in the form's show method.

 

Any ideas?

 

Thanks!

Fede

 

Mar 3, 2010 at 4:52 PM

I'm not sure I can help, but if you post your code I might have a better chance.

Mar 3, 2010 at 5:15 PM

XAML

                <my:DockingManager Name="mainDockManager" Background="Black" Loaded="mainDockManager_Loaded" Margin="0,-49.5,-9.333,0">
					<my:ResizingPanel Name="resizablePanle" >
					</my:ResizingPanel>
                </my:DockingManager>

On Window Loading

 

  for (int i = 0; i < contentPanelData.Count; i++)
            {
                ContentControl contentControl = new ContentControl();
                RegionManager.SetRegionName(contentControl, contentPanelData[i].RegionName);
                DockablePane dockPanel = new DockablePane();
                dockPanel.Name = contentPanelData[i].ContentControlName;
             
                DockableContent dockContent = new DockableContent();
                dockContent.Title = contentPanelData[i].PanelTitle;
                dockContent.Content = contentControl;
                dockPanel.Items.Add(dockContent);
                dockContent.Name = contentPanelData[i].ContentControlName + "Content";
                this.resizablePanle.Children.Add(dockPanel);

            }


And then the loading

this.mainDockManager.RestoreLayout("Layout.xml");