我正在评估AvalonDock是否适合新项目,并且已经实现了LayoutRoot类文档中显示的示例。我添加了在关机和启动时保存和恢复布局的方法。从下图中可以看出,布局正在正确恢复,但在从文件重新加载布局后,PropertyGrid不再显示当前文档中的内容。我怀疑这与来自XAML中另一个元素的内容有关,但无法弄清楚如何在重新加载布局后正确显示它。在重新加载布局后,我尝试在不同时间手动调用PropertyGrid.Update(),但没有成功。任何人都可以解释为什么这不符合我的预期,如果可能的话如何让它工作?
图1:PropertyGrid在保存之前显示文档1中按钮的属性。
图2:PropertyGrid在重新加载已保存的布局后不显示文档1中按钮的属性。
示例中的XAML:
<xcad:LayoutRoot x:Name="_layoutRoot" >
<xcad:LayoutPanel Orientation="Horizontal">
<xcad:LayoutAnchorablePane DockWidth="200">
<xcad:LayoutAnchorable ContentId="properties" Title="Properties" CanHide="False" CanClose="False"
AutoHideWidth="240" >
<!--IconSource="Images/property-blue.png"-->
<xctk:PropertyGrid NameColumnWidth="110" Name="pg"
SelectedObject="{Binding ElementName=_layoutRoot, Path=LastFocusedDocument.Content}" />
</xcad:LayoutAnchorable>
</xcad:LayoutAnchorablePane>
<xcad:LayoutDocumentPaneGroup >
<xcad:LayoutDocumentPane>
<xcad:LayoutDocument ContentId="document1" Title="Document 1" IconSource="Images/document.png" >
<Button Content="Document 1 Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</xcad:LayoutDocument>
<xcad:LayoutDocument ContentId="document2" Title="Document 2" IconSource="Images/document.png">
<TextBox Text="Document 2 Content" AcceptsReturn="True"/>
</xcad:LayoutDocument>
</xcad:LayoutDocumentPane>
</xcad:LayoutDocumentPaneGroup >
<xcad:LayoutAnchorablePaneGroup DockWidth="125">
<xcad:LayoutAnchorablePane>
<xcad:LayoutAnchorable ContentId="alarms" Title="Alarms" >
<!--IconSource="../Images/alarm-clock-blue.png"-->
<ListBox>
<s:String>Alarm 1</s:String>
<s:String>Alarm 2</s:String>
<s:String>Alarm 3</s:String>
</ListBox>
</xcad:LayoutAnchorable>
<xcad:LayoutAnchorable ContentId="journal" Title="Journal" >
<RichTextBox>
<FlowDocument>
<Paragraph FontSize="14" FontFamily="Segoe">
This is the content of the Journal Pane.
<LineBreak/>
A
<Bold>RichTextBox</Bold> has been added here
</Paragraph>
</FlowDocument>
</RichTextBox>
</xcad:LayoutAnchorable>
</xcad:LayoutAnchorablePane>
</xcad:LayoutAnchorablePaneGroup>
</xcad:LayoutPanel>
<xcad:LayoutRoot.LeftSide>
<xcad:LayoutAnchorSide>
<xcad:LayoutAnchorGroup>
<xcad:LayoutAnchorable Title="Agenda" ContentId="agenda" >
<!--IconSource="../Images/address-book-open.png"-->
<TextBlock Text="Agenda Content" Margin="10" FontSize="18" FontWeight="Black" TextWrapping="Wrap"/>
</xcad:LayoutAnchorable>
<xcad:LayoutAnchorable Title="Contacts" ContentId="contacts" >
<!--IconSource="../Images/address-book-pencil.png"-->
<TextBlock Text="Contacts Content" Margin="10" FontSize="18" FontWeight="Black" TextWrapping="Wrap"/>
</xcad:LayoutAnchorable>
</xcad:LayoutAnchorGroup>
</xcad:LayoutAnchorSide>
</xcad:LayoutRoot.LeftSide>
</xcad:LayoutRoot>
重新加载布局的方法:
private void LoadDockingManagerLayout(DockingManager docManager)
{
string layoutFileName = System.IO.Path.Combine(DirAppData, LayoutFileName);
if (System.IO.File.Exists(layoutFileName) == false)
return;
var layoutSerializer = new XmlLayoutSerializer(docManager);
layoutSerializer.Deserialize(layoutFileName);
}
答案 0 :(得分:1)
您必须附加LayoutSerializationCallback
实例引发的DockingManager
,然后在其中设置序列化布局的Content
。像这样:
var layoutSerializer = new XmlLayoutSerializer(this.DockManager);
layoutSerializer.LayoutSerializationCallback += layoutSerializer_LayoutSerializationCallback;
protected virtual void layoutSerializer_LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)
{
try
{
var model = this.Docs.Union(this.Tools).FirstOrDefault(vm => vm.ContentId == e.Model.ContentId);
if (model != null)
{
e.Content = model;
}
else
{
// Log load layout error info
}
}
catch (Exception ex)
{
// Log load layout error info
}
}
答案 1 :(得分:0)
原来,重新加载的布局会替换启动时创建的布局。因此,对_layoutRoot的引用不再有效。所以我不得不重新创建这样的绑定:
Binding myBinding = new Binding("LastFocusedDocument.Content");
myBinding.Source = docManager.Layout;
pg.SetBinding(PropertyGrid.SelectedObjectProperty, myBinding);