我正在尝试绑定Width
中浮动(未停靠)文档的Height
和AvalonDock
属性。我正在使用MVVM
模式
我想保存属性(连同对接状态和窗口的位置,如果未对接)并能够恢复它们。使用XmlLayoutSerializer
不是一个选项,因为这需要对ViewModel中不允许的对接管理器的引用。
这是XAML代码:
<avalonDock:DockingManager DocumentsSource="{Binding Files}"
ActiveContent="{Binding ActiveDocument, Mode=TwoWay}">
<avalonDock:DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type avalonDock:LayoutDocumentItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="CanClose" Value="False" />
<Setter Property="CanFloat" Value="True" />
</Style>
</avalonDock:DockingManager.LayoutItemContainerStyle>
<avalonDock:LayoutRoot>
<avalonDock:LayoutPanel>
<avalonDock:LayoutDocumentPane>
</avalonDock:LayoutDocumentPane>
</avalonDock:LayoutPanel>
</avalonDock:LayoutRoot>
ViewModel:
private ObservableCollection<PaneViewModel> m_readonyFiles;
public ObservableCollection<PaneViewModel> Files
{
get { return m_readonyFiles ?? (m_readonyFiles =
new ObservableCollection<PaneViewModel>()); }
}
private PaneViewModel _activeDocument = null;
public PaneViewModel ActiveDocument
{
get { return _activeDocument; }
set
{
if (_activeDocument != value)
{
_activeDocument = value;
RaisePropertyChanged("ActiveDocument");
}
}
}
我尝试以LayoutDocumentItem
的样式设置绑定,但是setter永远不会被调用:
<Window.Resources>
<Style TargetType="{x:Type avalonDock:LayoutDocumentItem}">
<Setter Property="Width" Value="{Binding ActiveDocument.CurrentWidth, Mode=TwoWay}"></Setter>
<Setter Property="Height" Value="{Binding ActiveDocument.CurrentHeigth, Mode=TwoWay}"></Setter>
</Style>
</Window.Resources>
如何在不违反MVVM模式的情况下保存和恢复浮动文档的大小和位置?
解决方案更新&gt;&gt;&gt;
我终于通过@Sheridan在其答案中链接的一篇文章中的一个想法解决了我的问题。我创建了一个信使,用于处理我的ViewModel和View的CodeBehind之间的通信。在那里,我获得文档的位置和大小,并将它们发送回ViewModel。要恢复,我使用ILayoutUpdateStrategy
并在函数AfterInsertDocument
中恢复状态。
答案 0 :(得分:2)
在WPF中,我们操纵数据元素而不是 UI元素。因此,只需保存相关的属性值,而不是尝试保存UI控件及其荒谬的属性。通常,执行此操作的最佳方法是声明包含所需属性类型和值的自定义类。
但是,在AvalonDock的情况下,DockingManager
对象有一个方便的扩展函数来处理这个问题:
/// <summary>
/// Event raised when the window is about to close.
/// </summary>
private void Window_Closing(object sender, CancelEventArgs e)
{
...
//
// When the window is closing, save AvalonDock layout to a file.
//
avalonDockHost.DockingManager.SaveLayout(LayoutFileName);
}
...
/// <summary>
/// Event raised when AvalonDock has loaded.
/// </summary>
private void avalonDockHost_AvalonDockLoaded(object sender, EventArgs e)
{
if (System.IO.File.Exists(LayoutFileName))
{
//
// If there is already a saved layout file, restore AvalonDock layout from it.
//
avalonDockHost.DockingManager.RestoreLayout(LayoutFileName);
}
else
{
//
// ... no previously saved layout exists, need to load default layout ...
//
}
}
这些示例来自代码项目的AvalonDock and MVVM页面,您可能会因其他原因而感兴趣。有关该主题的进一步帮助,请参阅代码项目的Loading/Saving AvalonDock Layouts at Start-up/Shut-Down页面,或CodePlex的AvalonDock部分的Save/Load Layout & Content和AvalonDock 2.0 getting started guide PART 2页面。