How to bind ApplicationCommands to a ViewModel? How to bind ApplicationCommands to a ViewModel? wpf wpf

How to bind ApplicationCommands to a 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!

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

The Behavior class:

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;        }    }}

The 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>


I believe that you are looking for CommandBindings. I use something similar for some textboxes:

    <DataTemplate x:Key="textBoxTemplate" >        <TextBox>            <TextBox.CommandBindings>                <CommandBinding Command="ApplicationCommand.Copy"                                 Executed="CommandBinding_Executed"                                CanExecute="CommandBinding_CanExecute">                </CommandBinding>            </TextBox.CommandBindings>        </TextBox>    </DataTemplate>

Note that PreviewCanExecute and PreviewExecuted are also available.

Edit: Check out the sample here to make it MVVM compliant.