wpf AvalonDock DockingManager 不加载布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15970888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:35:12  来源:igfitidea点击:

AvalonDock DockingManager does not load layout

c#wpfxml-serializationavalondock

提问by ceco

In order to save and load my layout I followed the instructions here, but it didn't work for me.

为了保存和加载我的布局,我按照此处的说明进行操作,但它对我不起作用。

I've got this XAMLinside the MainWindow:

我在XAML里面有这个MainWindow

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

And these are the event handlers for the button clicks:

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

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

After the window is shown and I click save the content of the "test" file is:

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

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

Here comes the problem - after I click the load button the document and the anchorable disappear and all I can see in the window are the 2 buttons and an empty rectangle where my layout should be. At this point when I click the save button this is what is written to the "test" file:

问题来了 - 在我点击加载按钮后,文档和锚点消失了,我在窗口中看到的只有 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>

I am using AvalonDock 2.0.1746.0. Anyone knows how to fix it?

我正在使用 AvalonDock 2.0.1746.0。有谁知道如何修复它?

回答by computerulz

Edit:

编辑:

I tried your code out, and compared it's output to mine, and found that your serialized file is missing the ContentIdproperty for your LayoutDocumentand LayoutAnchorable. This property is what AvalonDock uses internally to match up the existing DockingManagerpanels with the serialized versions, and without it, as you have seen, nothing works.

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

There are also 2 methods that can be used to set the ContentIdproperty, either explicitly as a property of the specific AvalonDock panel, or implicitly by setting the Nameproperty on the immediate child of the panel. Here is your revised main window XAML code with both ways used.

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

If you use the Save and Load buttons now, you will see the ContentIdproperties are now set in the test file, as below.

如果您现在使用 Save 和 Load 按钮,您将看到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>

For future reference on how to debug this issue, I did actually use the callback below in order to debug and check the values returned by the deserialization process, where the eparameter contains the deserialized version of the AvalonDock panel in the Modelproperty, (which in your case was originally null), and if the ContentIdproperty is correct, will contain you panel's content in its Contentproperty (this was also null due to the null value in the ContentIdproperty of the Model).

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

The sin the callback handler contains the XmlLayoutSerializerreference, which also contains a reference to the DockingManager, through which you can inspect the current items contained within it.

s回调处理程序包含了XmlLayoutSerializer参考,其中也包含了参考DockingManager,通过它你可以检查它所包含的当前项目。

Old:

老的:

I remember having a similar issue with an earlier version of the AvalonDock, but I think what fixed it for me was upgrading to the latest version (which you already have), as there was an internal part not deserializing properly.

我记得早期版本的 AvalonDock 也有类似的问题,但我认为对我来说修复它的是升级到最新版本(你已经有了),因为有一个内部部分没有正确反序列化。

However, to try find the issue with the deserialization process you could try putting a breakpoint in the LayoutSerializercallback. Hopefully that will give you more information as to what the particular issue is.

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

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