如何将ApplicationCommands绑定到ViewModel? [英] How to bind ApplicationCommands to a ViewModel?

查看:356
本文介绍了如何将ApplicationCommands绑定到ViewModel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地使用了一些使用MVVM-Light的自定义命令,但是我希望我的应用程序不仅对Window级别而且对详细的项目级别都响应标准的ApplicationCommands.

I have successfully used a few custom commands using MVVM-Light, but I want my application to respond to the standard ApplicationCommands, not just at a Window level, but at a detailed item level as well.

我有一个TreeView,我希望能够在其中复制和粘贴节点.每个TreeViewItem都有自己的ViewModel,由于存在几种不同的类型,因此它们在XAML中通过HierarchicalDataTemplates显示.我已经实现了在ViewModel类上复制,粘贴以及CanCopy和CanPaste的方法.如果合适,我可以很容易地实现指向这些的MVVM-Light RelayCommands,但这似乎并不正确.

I have a TreeView that I want to be able to copy and paste nodes in. Each TreeViewItem has its own ViewModel, and they are displayed via HierarchicalDataTemplates in XAML as there are several different types. I have implemented methods to copy, paste, as well as CanCopy and CanPaste on my ViewModel classes. If appropriate, I could implement MVVM-Light RelayCommands pointing to these easily enough, but that doesn't seem right.

我想使用菜单Ctrl + C和Ctrl + V或最终使用上下文菜单访问命令.我也不想破坏UI中其他元素(例如TextBoxes)的复制/粘贴功能.为此目的,似乎应该使用内置的ApplicationCommands.但是,我仅在后台的UserControl代码中看到这些示例的示例.我没有(或以其他方式需要)UserControl,也不是真正跟随MVVM.

I would like to access the commands using a menu, Ctrl+C and Ctrl+V, or eventually a context menu. I also don't want to break copy/paste functionality for other elements in my UI, such as TextBoxes. It seems appropriate to use the built-in ApplicationCommands for this purpose. However, I am only seeing examples of these being handled in a UserControl code-behind. I don't have (or otherwise need) a UserControl, nor is that really following MVVM.

是否可以将ApplicationCommand.CopyApplicationCommand.Paste命令绑定到我的ViewModel,即在数据模板中?

Is there a way I can bind ApplicationCommand.Copy and ApplicationCommand.Paste commands to my ViewModels, i.e., in the data templates?

推荐答案

我已使用附加到TreeView的行为"解决了此问题. TreeViewItems或Templates似乎无法将命令路由到它们.幸运的是,TreeView还具有一个SelectedItem属性,可用于获取ViewModel!

I have resolved this using Behaviors attached to the TreeView. The TreeViewItems or Templates to not seem to get the commands routed to them. Fortunately, the TreeView also has a SelectedItem property that can be used to get the ViewModel!

(行为在概念上类似于@Natxo的答案中的链接中的解决方案,但不能解决所有问题.)

(Behaviors are conceptually similar to the solution in the link in @Natxo's answer, but it doesn't resolve everything.)

行为类:

public class TreeViewClipboardBehavior : Behavior<TreeView>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        CommandBinding CopyCommandBinding = new CommandBinding(
            ApplicationCommands.Copy,
            CopyCommandExecuted,
            CopyCommandCanExecute);
        AssociatedObject.CommandBindings.Add(CopyCommandBinding);

        CommandBinding CutCommandBinding = new CommandBinding(
            ApplicationCommands.Cut,
            CutCommandExecuted,
            CutCommandCanExecute);
        AssociatedObject.CommandBindings.Add(CutCommandBinding);

        CommandBinding PasteCommandBinding = new CommandBinding(
            ApplicationCommands.Paste,
            PasteCommandExecuted,
            PasteCommandCanExecute);
        AssociatedObject.CommandBindings.Add(PasteCommandBinding);
    }

    private void CopyCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanCopyToClipboard)
        {
            item.CopyToClipboard();
            e.Handled = true;
        }
    }

    private void CopyCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanCopyToClipboard;
            e.Handled = true;
        }
    }

    private void CutCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanCutToClipboard)
        {
            item.CutToClipboard();
            e.Handled = true;
        }
    }

    private void CutCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanCutToClipboard;
            e.Handled = true;
        }
    }


    private void PasteCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanPasteFromClipboard)
        {
            item.PasteFromClipboard();
            e.Handled = true;
        }
    }

    private void PasteCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanPasteFromClipboard;
            e.Handled = true;
        }
    }
}

XAML

<TreeView Grid.Row="2" ItemsSource="{Binding SystemTreeRoot}">
    <i:Interaction.Behaviors>
        <local:TreeViewClipboardBehavior/>
    </i:Interaction.Behaviors>
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:MyViewModel}" ItemsSource="{Binding Children}">
            <!-- Template content -->
        </HierarchicalDataTemplate>
</TreeView>

这篇关于如何将ApplicationCommands绑定到ViewModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆