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