用MVVM绑定AvalonDock中浮动元素的大小和位置

本文关键字:位置 元素 绑定 MVVM AvalonDock | 更新日期: 2023-09-27 18:05:34

我试图在AvalonDock中绑定浮动(未停靠)文档的WidthHeight属性。我使用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模式?


解决方案更新>>

我终于解决了我的问题与一个想法从一篇文章@谢里丹链接在他的回答。我创建了一个信使来处理ViewModel和View的CodeBehind之间的通信。在那里我获得文档的位置和大小,并将它们发送回ViewModel。为了恢复,我使用ILayoutUpdateStrategy,并在函数AfterInsertDocument中恢复状态。

用MVVM绑定AvalonDock中浮动元素的大小和位置

在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部分