从文件重新加载布局的AvalonDock LayoutRoot示例不显示属性

时间:2018-05-23 02:22:16

标签: c# xaml avalondock xceed

我正在评估AvalonDock是否适合新项目,并且已经实现了LayoutRoot类文档中显示的示例。我添加了在关机和启动时保存和恢复布局的方法。从下图中可以看出,布局正在正确恢复,但在从文件重新加载布局后,PropertyGrid不再显示当前文档中的内容。我怀疑这与来自XAML中另一个元素的内容有关,但无法弄清楚如何在重新加载布局后正确显示它。在重新加载布局后,我尝试在不同时间手动调用PropertyGrid.Update(),但没有成功。任何人都可以解释为什么这不符合我的预期,如果可能的话如何让它工作?

PropertyGrid showing properties of button in Document 1 图1:PropertyGrid在保存之前显示文档1中按钮的属性。

PropertyGrid NOT showing properties of button in Document 1 图2:PropertyGrid在重新加载已保存的布局后不显示文档1中按钮的属性。

示例中的XAML:

<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>

重新加载布局的方法:

    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);
    }

2 个答案:

答案 0 :(得分:1)

您必须附加LayoutSerializationCallback实例引发的DockingManager,然后在其中设置序列化布局的Content。像这样:

var layoutSerializer = new XmlLayoutSerializer(this.DockManager);
layoutSerializer.LayoutSerializationCallback += layoutSerializer_LayoutSerializationCallback;

protected virtual void layoutSerializer_LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)
{
    try
    {
        var model = this.Docs.Union(this.Tools).FirstOrDefault(vm => vm.ContentId == e.Model.ContentId);
        if (model != null)
        {
            e.Content = model;
        }
        else
        {
            // Log load layout error info                    
        }
    }
    catch (Exception ex)
    {
        // Log load layout error info    
    }
}

答案 1 :(得分:0)

原来,重新加载的布局会替换启动时创建的布局。因此,对_layoutRoot的引用不再有效。所以我不得不重新创建这样的绑定:

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