【问题标题】:AvalonDock DockingManager does not load layoutAvalonDock DockingManager 不加载布局
【发布时间】:2013-04-04 22:52:17
【问题描述】:

为了保存和加载我的布局,我遵循了here 的说明,但它对我不起作用。

我在MainWindow 中有这个XAML

<StackPanel Orientation="Vertical">
    <Button Content="Save"
            Click="SaveButton_Click"/>
    <Button Content="Load"
            Click="LoadButton_Click"/>
    <ad:DockingManager x:Name="myDM">
        <ad:LayoutRoot>
            <ad:LayoutPanel>
                <ad:LayoutDocumentPane>
                    <ad:LayoutDocument Title="Document">
                        <TextBox />
                    </ad:LayoutDocument>
                </ad:LayoutDocumentPane>
            </ad:LayoutPanel>
            <ad:LayoutRoot.LeftSide>
                <ad:LayoutAnchorSide>
                    <ad:LayoutAnchorGroup>
                        <ad:LayoutAnchorable Title="Left">
                            <TextBox/>
                        </ad:LayoutAnchorable>
                    </ad:LayoutAnchorGroup>
                </ad:LayoutAnchorSide>
            </ad:LayoutRoot.LeftSide>
        </ad:LayoutRoot>
    </ad:DockingManager>
</StackPanel>

这些是按钮点击的事件处理程序:

private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    XmlLayoutSerializer layoutSerializer = new XmlLayoutSerializer(myDM);
    using (var writer = new StreamWriter("test"))
    {
        layoutSerializer.Serialize(writer);
    }
}

private void LoadButton_Click(object sender, RoutedEventArgs e)
{
    XmlLayoutSerializer layoutSerializer = new XmlLayoutSerializer(myDM);
    using (var reader = new StreamReader("test"))
    {
        layoutSerializer.Deserialize(reader);
    }
}

显示窗口后,我点击保存“测试”文件的内容是:

<?xml version="1.0" encoding="utf-8"?>
<LayoutRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <RootPanel Orientation="Horizontal">
    <LayoutDocumentPane>
      <LayoutDocument Title="Document" IsSelected="True" IsLastFocusedDocument="True" LastActivationTimeStamp="04/12/2013 14:50:38" />
    </LayoutDocumentPane>
  </RootPanel>
  <TopSide />
  <RightSide />
  <LeftSide>
    <LayoutAnchorGroup>
      <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Left" />
    </LayoutAnchorGroup>
  </LeftSide>
  <BottomSide />
  <FloatingWindows />
  <Hidden />
</LayoutRoot>

问题来了 - 在我单击加载按钮后,文档和可锚定项消失了,我在窗口中看到的只有 2 个按钮和一个空矩形,我的布局应该是。此时,当我单击保存按钮时,这是写入“测试”文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<LayoutRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <RootPanel Orientation="Horizontal">
    <LayoutDocumentPane />
  </RootPanel>
  <TopSide />
  <RightSide />
  <LeftSide>
    <LayoutAnchorGroup Id="d3710e74-e6b5-4541-8b6f-554197c29dd6" />
  </LeftSide>
  <BottomSide />
  <FloatingWindows />
  <Hidden>
    <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Left" IsSelected="True" LastActivationTimeStamp="04/12/2013 14:53:56" PreviousContainerId="d3710e74-e6b5-4541-8b6f-554197c29dd6" PreviousContainerIndex="0" />
  </Hidden>
</LayoutRoot>

我正在使用 AvalonDock 2.0.1746.0。谁知道怎么解决?

【问题讨论】:

    标签: c# wpf xml-serialization avalondock


    【解决方案1】:

    编辑:

    我尝试了您的代码,并将其输出与我的比较,发现您的序列化文件缺少LayoutDocumentLayoutAnchorableContentId 属性。这个属性是 AvalonDock 在内部用来匹配现有的DockingManager 面板和序列化版本的,没有它,正如你所见,没有任何工作。

    还有 2 种方法可用于设置 ContentId 属性,或者显式作为特定 AvalonDock 面板的属性,或者通过在面板的直接子级上设置 Name 属性来隐式设置。这是您修改后的主窗口 XAML 代码,两种方式都使用了。

    <StackPanel Orientation="Vertical">
        <Button Content="Save"
        Click="SaveButton_Click"/>
        <Button Content="Load"
        Click="LoadButton_Click"/>
        <ad:DockingManager x:Name="myDM">
            <ad:LayoutRoot>
                <ad:LayoutPanel>
                    <ad:LayoutDocumentPane>
                        <ad:LayoutDocument Title="Document" ContentId="IHaveContent">
                            <TextBox />
                        </ad:LayoutDocument>
                    </ad:LayoutDocumentPane>
                </ad:LayoutPanel>
                <ad:LayoutRoot.LeftSide>
                    <ad:LayoutAnchorSide>
                        <ad:LayoutAnchorGroup>
                            <ad:LayoutAnchorable Title="Left">
                                <TextBox x:Name="IAmTextBoxContent"/>
                            </ad:LayoutAnchorable>
                        </ad:LayoutAnchorGroup>
                    </ad:LayoutAnchorSide>
                </ad:LayoutRoot.LeftSide>
            </ad:LayoutRoot>
        </ad:DockingManager>
    </StackPanel>
    

    如果您现在使用保存和加载按钮,您将看到 ContentId 属性现在已在测试文件中设置,如下所示。

    <?xml version="1.0" encoding="utf-8"?>
    <LayoutRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <RootPanel Orientation="Horizontal">
        <LayoutDocumentPane>
          <LayoutDocument Title="Document" 
              IsSelected="True" 
              IsLastFocusedDocument="True" 
              ContentId="IHaveContent" 
              LastActivationTimeStamp="04/17/2013 09:13:35" />
        </LayoutDocumentPane>
      </RootPanel>
      <TopSide />
      <RightSide />
      <LeftSide>
        <LayoutAnchorGroup>
          <LayoutAnchorable AutoHideMinWidth="100" 
              AutoHideMinHeight="100" 
              Title="Left" 
              ContentId="IAmTextBoxContent" />
        </LayoutAnchorGroup>
      </LeftSide>
      <BottomSide />
      <FloatingWindows />
      <Hidden />
    </LayoutRoot>
    

    为了将来如何调试此问题的参考,我确实使用下面的回调来调试和检查反序列化过程返回的值,其中e 参数包含反序列化版本的 AvalonDock 面板Model 属性(在您的情况下最初为 null),如果 ContentId 属性正确,将在其 Content 属性中包含您面板的内容(由于 @987654334 中的 null 值,这也是 null Model 的 @ 属性)。

    回调处理程序中的s 包含XmlLayoutSerializer 引用,其中还包含对DockingManager 的引用,通过它您可以检查其中包含的当前项。

    旧:

    我记得早期版本的 AvalonDock 也有类似的问题,但我认为为我解决的问题是升级到最新版本(您已经拥有),因为内部部分没有正确反序列化。

    但是,要尝试找出反序列化过程的问题,您可以尝试在 LayoutSerializer 回调中放置一个断点。希望这将为您提供有关特定问题的更多信息。

    layoutSerializer.LayoutSerializationCallback += (s, e) =>
    {
        object o = e.Content;
    };
    

    【讨论】:

    • 感谢您的回答。你的意思是我必须得到 AvalonDock 源并调试它?
    • ,感谢您的回答。出现了一个具有更高优先级的问题,我一直在处理它。当我有时间解决这个问题时,我会调查它并可能接受您的回答。
    • 感谢您的意见。我接受你的回答。或者,我找到了另一种让它按预期工作的方法。它不设置 ContentId 或内容的名称。我只是在反序列化之前使用空方法订阅了 LayoutSerializationCallback 事件。
    • 很高兴知道有不止一种方法可以做到这一点,因为似乎与 .NET 相关的大多数事情都...我会试一试,听起来更容易管理.谢谢。
    • 我认为你的方法更干净,因为另一种方法太老套了。无论如何设置一些 ContentId 并不是什么负担。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多