Search code examples
c#xamlavalondockxceed

AvalonDock LayoutRoot example with layout reloaded from file doesn't show properties


I am assessing AvalonDock for suitability for a new project and have implemented the example shown in the documentation of the LayoutRoot class. I have added methods to save and restore the layout on shutdown and startup. As can be seen in the images below, the layout is being restored properly, but after the layout is reloaded from the file, the PropertyGrid no longer shows the content from the current document. I suspect this has something to do with the content coming from another element in the XAML, but can't figure out how to get it to display properly after the layout is reloaded. I have tried manually calling PropertyGrid.Update() at various times after the layout is reloaded without any success. Can anyone please explain why this is not working as I expect and how to make it work, if possible?

PropertyGrid showing properties of button in Document 1 Image 1: PropertyGrid showing properties of button in Document 1 before saving.

PropertyGrid NOT showing properties of button in Document 1 Image 2: PropertyGrid NOT showing properties of button in Document 1 after reloading saved layout.

XAML from example:

<xcad:LayoutRoot x:Name="_layoutRoot" >
    <xcad:LayoutPanel Orientation="Horizontal">
        <xcad:LayoutAnchorablePane DockWidth="200">
            <xcad:LayoutAnchorable ContentId="properties" Title="Properties" CanHide="False" CanClose="False"
                                AutoHideWidth="240" >
                <!--IconSource="Images/property-blue.png"-->
                <xctk:PropertyGrid NameColumnWidth="110" Name="pg"
                                   SelectedObject="{Binding ElementName=_layoutRoot, Path=LastFocusedDocument.Content}" />
            </xcad:LayoutAnchorable>
        </xcad:LayoutAnchorablePane>

        <xcad:LayoutDocumentPaneGroup >
            <xcad:LayoutDocumentPane>
                <xcad:LayoutDocument ContentId="document1" Title="Document 1" IconSource="Images/document.png" >
                    <Button Content="Document 1 Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </xcad:LayoutDocument>

                <xcad:LayoutDocument ContentId="document2" Title="Document 2" IconSource="Images/document.png">
                    <TextBox Text="Document 2 Content" AcceptsReturn="True"/>
                </xcad:LayoutDocument>
            </xcad:LayoutDocumentPane>
        </xcad:LayoutDocumentPaneGroup >

        <xcad:LayoutAnchorablePaneGroup DockWidth="125">
            <xcad:LayoutAnchorablePane>
                <xcad:LayoutAnchorable ContentId="alarms" Title="Alarms"  >
                    <!--IconSource="../Images/alarm-clock-blue.png"-->
                    <ListBox>
                        <s:String>Alarm 1</s:String>
                        <s:String>Alarm 2</s:String>
                        <s:String>Alarm 3</s:String>
                    </ListBox>
                </xcad:LayoutAnchorable>

                <xcad:LayoutAnchorable ContentId="journal" Title="Journal" >
                    <RichTextBox>
                        <FlowDocument>
                            <Paragraph FontSize="14" FontFamily="Segoe">
                                This is the content of the Journal Pane.
                                <LineBreak/>
                                A
                                <Bold>RichTextBox</Bold> has been added here
                            </Paragraph>
                        </FlowDocument>
                    </RichTextBox>
                </xcad:LayoutAnchorable>
            </xcad:LayoutAnchorablePane>
        </xcad:LayoutAnchorablePaneGroup>
    </xcad:LayoutPanel>

    <xcad:LayoutRoot.LeftSide>
        <xcad:LayoutAnchorSide>
            <xcad:LayoutAnchorGroup>
                <xcad:LayoutAnchorable Title="Agenda" ContentId="agenda" >
                    <!--IconSource="../Images/address-book-open.png"-->
                    <TextBlock Text="Agenda Content" Margin="10" FontSize="18" FontWeight="Black" TextWrapping="Wrap"/>
                </xcad:LayoutAnchorable>

                <xcad:LayoutAnchorable Title="Contacts" ContentId="contacts"  >
                    <!--IconSource="../Images/address-book-pencil.png"-->
                    <TextBlock Text="Contacts Content" Margin="10" FontSize="18" FontWeight="Black" TextWrapping="Wrap"/>
                </xcad:LayoutAnchorable>
            </xcad:LayoutAnchorGroup>
        </xcad:LayoutAnchorSide>
    </xcad:LayoutRoot.LeftSide>
</xcad:LayoutRoot>

Method that reloads the layout:

    private void LoadDockingManagerLayout(DockingManager docManager)
    {
        string layoutFileName = System.IO.Path.Combine(DirAppData, LayoutFileName);

        if (System.IO.File.Exists(layoutFileName) == false)
            return;

        var layoutSerializer = new XmlLayoutSerializer(docManager);

        layoutSerializer.Deserialize(layoutFileName);
    }

Solution

  • Turns out that the reloaded layout replaces the layout created at startup. So the reference to _layoutRoot is no longer valid. So I had to recreate the binding like this:

            Binding myBinding = new Binding("LastFocusedDocument.Content");
            myBinding.Source = docManager.Layout;
            pg.SetBinding(PropertyGrid.SelectedObjectProperty, myBinding);