AvalonDock 2.0:在反序列化布局后添加 LayoutDocument 不起作用
AvalonDock 2.0: adding LayoutDocument not working after Deserialize layout
只有 LayoutDocumentPane 的简单 AvalonDock 应用程序。
XAML:
<Window x:Name="MainWindow1" x:Class="AvalonTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
Title="MainWindow" Height="350" Width="525" Loaded="MainWindow1_Loaded">
<Grid Name="MainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0" Grid.Column="0">
<Button Content="New Tab" Margin="10,0,0,0" Click="NewTabClick"/>
<Button Content="Save layout" Margin="10,0,0,0" Click="Button_Click"/>
</ToolBar>
<xcad:DockingManager x:Name="dockManager" Grid.Row="1">
<xcad:LayoutRoot x:Name="_layoutRoot">
<xcad:LayoutPanel Orientation="Horizontal" x:Name="_layoutPanel">
<xcad:LayoutDocumentPane x:Name="workSpace">
<xcad:LayoutDocument ContentId="dummy" Title="Dummy" >
<Button x:Name="dummyButton" Content="Dummy Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</xcad:LayoutDocument>
</xcad:LayoutDocumentPane>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
</Window>
代码:
using System;
using System.IO;
using System.Windows;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;
namespace AvalonTest2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NewTabClick(object sender, RoutedEventArgs e)
{
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
workSpace.Children.Add(ld);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var layoutSerial = new XmlLayoutSerializer(dockManager);
layoutSerial.Serialize("layout.xml");
}
private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{
if (File.Exists("layout.xml"))
{
// var serializer = new XmlLayoutSerializer(dockManager);
// serializer.Deserialize("layout.xml");
}
}
}
}
我按下 "New tab" 按钮,一切正常:出现新标签页。
我重新启动程序,保存布局("Save layout" 按钮),关闭程序并删除反序列化行上的注释。
我启动程序并在按下 "New tab" 时没有出现任何选项卡。我会查看 LayoutDocumentPane (workSpace),"Children" 属性 充满了新文档。
怎么了?
不幸的是,(反)序列化功能在 AvalonDock
套件中实现得不是很好。
反序列化时,将创建一个全新的 LayoutRoot
对象。您在 XAML 中定义一个名称为 workSpace
的 LayoutDocumentPane
,并将新创建的 LayoutDocument
添加到此窗格中。但是,反序列化后,这个 LayoutDocumentPane
不再属于布局 - 它已被删除;而是创建了一个新的 LayoutDocumentPane
。
因此您看不到添加到 workSpace
容器中的任何 LayoutDocument
视图。
不要按名称引用 LayoutDocumentPane
的实例,而是动态查找它。您必须将代码更改为:
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
LayoutDocumentPane documentPane = this.dockManager.Layout.Descendents().OfType<LayoutDocumentPane>().SingleOrDefault();
if (documentPane != null)
{
documentPane.Children.Add(ld);
}
自从 使我免于完全放弃 Avalon Dock,我想我也会在这里提供 VB 解决方案。我所做的唯一小改动是将 SingleOrDefault 更改为 FirstOrDefault:
Dim documentPane As LayoutDocumentPane = me.dockManager.Layout.Descendents().OfType(Of LayoutDocumentPane).FirstOrDefault()
If Not IsNothing(documentPane) Then
documentPane.Children.Add(ld)
End If
只有 LayoutDocumentPane 的简单 AvalonDock 应用程序。
XAML:
<Window x:Name="MainWindow1" x:Class="AvalonTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
Title="MainWindow" Height="350" Width="525" Loaded="MainWindow1_Loaded">
<Grid Name="MainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0" Grid.Column="0">
<Button Content="New Tab" Margin="10,0,0,0" Click="NewTabClick"/>
<Button Content="Save layout" Margin="10,0,0,0" Click="Button_Click"/>
</ToolBar>
<xcad:DockingManager x:Name="dockManager" Grid.Row="1">
<xcad:LayoutRoot x:Name="_layoutRoot">
<xcad:LayoutPanel Orientation="Horizontal" x:Name="_layoutPanel">
<xcad:LayoutDocumentPane x:Name="workSpace">
<xcad:LayoutDocument ContentId="dummy" Title="Dummy" >
<Button x:Name="dummyButton" Content="Dummy Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</xcad:LayoutDocument>
</xcad:LayoutDocumentPane>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
</Window>
代码:
using System;
using System.IO;
using System.Windows;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;
namespace AvalonTest2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NewTabClick(object sender, RoutedEventArgs e)
{
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
workSpace.Children.Add(ld);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var layoutSerial = new XmlLayoutSerializer(dockManager);
layoutSerial.Serialize("layout.xml");
}
private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{
if (File.Exists("layout.xml"))
{
// var serializer = new XmlLayoutSerializer(dockManager);
// serializer.Deserialize("layout.xml");
}
}
}
}
我按下 "New tab" 按钮,一切正常:出现新标签页。
我重新启动程序,保存布局("Save layout" 按钮),关闭程序并删除反序列化行上的注释。
我启动程序并在按下 "New tab" 时没有出现任何选项卡。我会查看 LayoutDocumentPane (workSpace),"Children" 属性 充满了新文档。
怎么了?
不幸的是,(反)序列化功能在 AvalonDock
套件中实现得不是很好。
反序列化时,将创建一个全新的 LayoutRoot
对象。您在 XAML 中定义一个名称为 workSpace
的 LayoutDocumentPane
,并将新创建的 LayoutDocument
添加到此窗格中。但是,反序列化后,这个 LayoutDocumentPane
不再属于布局 - 它已被删除;而是创建了一个新的 LayoutDocumentPane
。
因此您看不到添加到 workSpace
容器中的任何 LayoutDocument
视图。
不要按名称引用 LayoutDocumentPane
的实例,而是动态查找它。您必须将代码更改为:
var ld = new LayoutDocument();
var x = new Random().Next().ToString();
ld.Title = x;
ld.ContentId = x;
LayoutDocumentPane documentPane = this.dockManager.Layout.Descendents().OfType<LayoutDocumentPane>().SingleOrDefault();
if (documentPane != null)
{
documentPane.Children.Add(ld);
}
自从
Dim documentPane As LayoutDocumentPane = me.dockManager.Layout.Descendents().OfType(Of LayoutDocumentPane).FirstOrDefault()
If Not IsNothing(documentPane) Then
documentPane.Children.Add(ld)
End If