This project is read-only.

RestoreLayout with programmatically added panes

Oct 14, 2008 at 12:27 AM
Edited Oct 14, 2008 at 12:28 AM

This is a great docking library and I'm trying to incorporate it into a client app where user layout persistence is crutial.  I'm having a problem calling RestoreLayout on my document manager and having it restore panes that have be added to the manager programmatically.  Here's my XAML from a test project.

<ad:DockingManager Grid.Row="1" x:Name="dockManager">
    <ad:ResizingPanel x:Name="resizePanel" Orientation="Vertical">
        <ad:DockablePane x:Name="dockPane1" >
            <ad:DockableContent x:Name="dockContent1">
                <TextBlock Text="This is some content" />
            </ad:DockableContent>
        </ad:DockablePane>
    </ad:ResizingPanel>
</ad:DockingManager>

And here's my code behind:

DockableContent
cnt = new DockableContent();
cnt.Name =
"content2";
cnt.Content =
new TextBox();
cnt.Title =
"New Textbox";

DockablePane pane = new DockablePane();
pane.Items.Add(cnt);
pane.Name =
"pane1";
resizePanel.Children.Add(pane);
dockManager.Show(cnt,
DockableContentState.Docked, AnchorStyle.Bottom);

 The code will successfully add a new dockable pane with a textbox content every time it is called.  Here is the XML string that is created when SaveLayout is called:

<DockingManager>
    <ResizingPanel Orientation="Vertical">
        <DockablePane ResizeHeight="200" Anchor="Top">
            <DockableContent Name="dockContent1" AutoHide="false" />
        </DockablePane>
        <DockablePane Anchor="Left">
            <DockableContent Name="content2" AutoHide="false" />
        </DockablePane>
    </ResizingPanel>
    <Hidden />
    <Windows />
</DockingManager>

 Everything looks good so far, but when restore layout is called, the 'content2' DockableContent and it's parent pane are not restored.  Is this functionality possible with AvalonDock?  There may just be something that I am overlooking.

Oct 14, 2008 at 11:05 AM
Hi, you have to check if DockingManager.RestoreLayout() is called after you add 'content2'. When DockingManager restoring layout encounters a content with name 'content2', it looks for a content with that name in DockingManager.DockableContents array. If it can't find the content it simply skips to next entry.
In my internal version (posted soon) I added a way to dynamically provide content to AvalonDock when it needs.

Ado
Oct 14, 2008 at 3:24 PM
Thanks for your quick reply.  You are correct, I was calling DockingManager.RestoreLayout() when the application loads.  I was hoping that it would restore the panes and their positions and then I would extend the restore process and dynamically add the content back into the restored panes if the end user chooses to. 

What is the best way to add content to the DockingManager before DockingManager.RestoreLayout() is called?  For example, if I have some content displayed in a floating window when DockingManager.SaveLayout() is called, and I restart my application, re-add the content in a DockablePane and call DockingManager.RestoreLayout(), will it restore itself into a floating window?
Oct 14, 2008 at 4:40 PM
If you need to manage correctly layout persistance the rigth way is always to add all contents at startup in a fixed layout. For an example all contents docked to the right. Then call the RestoreLayout and leave AvalonDock rearrange your contents according to xml file. After this when user close the application or when you prefer call SaveLayout to store the layout again. You can even provide a default layout as xml file stored in an assemply resource, so the very first time your application starts you can provide that to RestoreLayout().
This is the strategy used in SharpDevelop and I suggest you to take a look at that code.

In pseudo code:
<ad:DockingManager Grid.Row="1" x:Name="dockManager">(intentionally empty)
</ad:DockingManager>

public Window()
{
    InitializeComponents();

    DockablePane dummyPane = new DockablePane()
    foreach (Contents to load)
        dummyPane.Items.Add(content);
    dockManager.Anchor(dummyPane, AnghorStyle.Right);
    
    //here call restorelayout
    if (xmlFileWithLayoutExist)
        dockManager.RestoreLayout(xmlFileWithLayout);
    else
        dockManager.RestoreLayout(GetDefaultLayoutFromAssemblyResource);
}

void OnClosing()
{
    dockManager.SaveLayout(xmlFileWithLayout);
}

Hope can help! Ado