5

我将 Avalondock 2.x 用于我的一个开源项目,如果关闭时文档脏了,应该可以取消关闭。

我正在使用 Caliburn Micro 和 Coroutine,我能够解决它的唯一方法是使用 CM 附加到事件

<i:EventTrigger EventName="DocumentClosing">
    <cal:ActionMessage MethodName="DocumentClosing">
        <cal:Parameter Value="$documentcontext" />
        <cal:Parameter Value="$eventArgs" />
    </cal:ActionMessage>
</i:EventTrigger>

事件 arg 具有取消属性。这个方法的问题是它对 MVVM 不是很友好,我创建了一个小助手方法来 Cooutinify 这个像

public IEnumerable<IResult> Coroutinify(IEnumerable<IResult> results, System.Action cancelCallback)
{
    return results.Select(r =>
        {
            if (r is CancelResult)
                cancelCallback();

            return r;
        });
}

像这样使用

public IEnumerable<IResult> DocumentClosing(ScriptEditorViewModel document, DocumentClosingEventArgs e)
{
    return Result.Coroutinify(HandleScriptClosing(document), () => e.Cancel = true);
}

这可行,但有点笨拙等,是否有更多的 MVVM 方法可以在 Avalondock 中关闭具有取消功能的文档?

编辑:源代码

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellView.xaml#L29

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellViewModel.cs#L110

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Result/ResultFactory.cs#L49

4

2 回答 2

4

我完成此操作的方法是绑定到 AvalonDock LayoutItem 的CloseCommand属性。当此绑定关联时,它会覆盖关闭文档的默认行为(“X”按钮,右键单击关闭/全部关闭)。然后,如果需要,您将完全负责删除(关闭)文档。

我设置它的方式是拥有一个包含 DocumentVM 的 ObservableCollection 的 DocumentManagerVM。每个 DocumentVM 都有一个名为 RequestCloseCommand 的 ICommand,它可以通过将自身从其拥有的 DocumentManagerVM 的 DocumentVM 集合中删除来关闭文档。

具体来说,在我的 DocumentVM 视图模型中,有一个 ICommand(我正在使用 mvvmLight RelayCommand)来执行关闭逻辑:

public RelayCommand RequestCloseCommand { get; private set; }
void RequestClose()
{
    // if you want to prevent the document closing, just return from this function
    // otherwise, close it by removing it from the collection of DocumentVMs
    this.DocumentManagerVM.DocumentVMs.Remove(this);
}

在您的视图中,在 LayoutItemContainerStyle 或 LayoutItemContainerStyleSelector 中设置您的绑定。

<ad:DockingManager
    DataContext="{Binding DocumentManagerVM}"
    DocumentsSource="{Binding DocumentVMs}">

    <ad:DockingManager.LayoutItemContainerStyle>
        <Style TargetType="{x:Type ad:LayoutItem}">
            <Setter Property="Title" Value="{Binding Model.Header}"/>
            <Setter Property="CloseCommand" Value="{Binding Model.RequestCloseCommand}"/>
        </Style>
    </ad:DockingManager.LayoutItemContainerStyle>

</ad:DockingManager>
于 2013-10-09T15:51:23.897 回答
0

我向 DockingManger 添加了一个依赖属性,它允许绑定到关闭命令:

public static class DocumentClosingBehavior
{
    #region Dependecy Property
    private static readonly DependencyProperty DocumentClosingCommandProperty = DependencyProperty.RegisterAttached
                (
                    "DocumentClosingCommand",
                    typeof(ICommand),
                    typeof(DocumentClosingBehavior),
                    new PropertyMetadata(DocumentClosingCommandPropertyChangedCallBack)
                );
    #endregion

    #region Methods
    public static void SetDocumentClosingCommand(this UIElement inUIElement, ICommand inCommand)
    {
        inUIElement.SetValue(DocumentClosingCommandProperty, inCommand);
    }

    private static ICommand GetDocumentClosingCommand(UIElement inUIElement)
    {
        return (ICommand)inUIElement.GetValue(DocumentClosingCommandProperty);
    }
    #endregion

    #region CallBack Method
    private static void DocumentClosingCommandPropertyChangedCallBack(DependencyObject inDependencyObject, DependencyPropertyChangedEventArgs inEventArgs)
    {
        DockingManager uiElement = inDependencyObject as DockingManager;
        if (null == uiElement) return;

        uiElement.DocumentClosing += (sender, args) =>
        {
            GetDocumentClosingCommand(uiElement).Execute(args);
        };
    }
    #endregion
}

在 XAML 中:

<xcad:DockingManager vm:DocumentClosingBehavior.DocumentClosingCommand="{Binding DocumentCloseCommand}" Grid.Row="2" 
                       AllowMixedOrientation="True"
                       BorderBrush="Black"
                       BorderThickness="1"
                       Theme="{Binding ElementName=_themeCombo, Path=SelectedItem.Tag}"
                       DocumentsSource="{Binding Documents}"
                       ActiveContent="{Binding ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}"
                       >

在我的 MainViewModel 中,我定义了一个 ICommand DocumentCloseCommand。

于 2021-10-11T10:54:45.957 回答