用MVVM绑定AvalonDock中浮动元素的大小和位置
本文关键字:位置 元素 绑定 MVVM AvalonDock | 更新日期: 2023-09-27 18:05:34
我试图在AvalonDock
中绑定浮动(未停靠)文档的Width
和Height
属性。我使用MVVM
模式。
我想保存属性(连同对接状态和窗口的位置,如果未停靠),并能够恢复它们。使用XmlLayoutSerializer
不是一个选项,因为这需要对对接管理器的引用,而这在ViewModel中是不允许的。
<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模式?
解决方案更新>>
我终于解决了我的问题与一个想法从一篇文章@谢里丹链接在他的回答。我创建了一个信使来处理ViewModel和View的CodeBehind之间的通信。在那里我获得文档的位置和大小,并将它们发送回ViewModel。为了恢复,我使用ILayoutUpdateStrategy
,并在函数AfterInsertDocument
中恢复状态。
在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 ...
//
}
}
这些示例取自Code Project上的AvalonDock和MVVM页面,您可能会因为其他原因而对其感兴趣。有关该主题的进一步帮助,请参阅代码项目启动/关闭页面的加载/保存AvalonDock布局,或保存/加载布局&内容和AvalonDock 2.0入门指南PART 2页关于CodePlex的AvalonDock部分