AvalonDock DockingManager не загружает макет

Чтобы сохранить и загрузить свой макет, я следовал приведенным здесь инструкциям, но у меня это не сработало.

У меня есть это 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>

А вот обработчики событий для нажатий кнопок:

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>

Здесь возникает проблема - после того, как я нажимаю кнопку загрузки, документ и привязка исчезают, и все, что я вижу в окне, - это две кнопки и пустой прямоугольник, где должен быть мой макет. В этот момент, когда я нажимаю кнопку "Сохранить", это записывается в "тестовый" файл:

<?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. Кто-нибудь знает, как это исправить?

1 ответ

Решение

Редактировать:

Я опробовал ваш код, сравнил его вывод с моим и обнаружил, что в вашем сериализованном файле отсутствует ContentId собственность для вашего LayoutDocument а также LayoutAnchorable, Это свойство - то, что 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 свойство (которое в вашем случае изначально было нулевым), и если ContentId свойство является правильным, будет содержать содержимое панели в своем Content свойство (это также было нулевым из-за нулевого значения в ContentId собственность Model).

s в обработчике обратного вызова содержит XmlLayoutSerializer ссылка, которая также содержит ссылку на DockingManager, с помощью которого вы можете проверить текущие элементы, содержащиеся в нем.

Старый:

Я помню, что у меня была похожая проблема с более ранней версией AvalonDock, но я думаю, что это исправило для меня обновление до последней версии (которая у вас уже есть), поскольку внутренняя часть не десериализовалась должным образом.

Однако, чтобы попытаться найти проблему с процессом десериализации, вы можете попытаться установить точку останова в LayoutSerializer Перезвоните. Надеюсь, что это даст вам больше информации о том, что конкретный вопрос.

layoutSerializer.LayoutSerializationCallback += (s, e) =>
{
    object o = e.Content;
};
Другие вопросы по тегам