I would like to use ApplicationCommands.Cut, copy, paste, save,... They seem interesting because of the command routing, keybindings and the fact that some controls use them. I understand how I can bind to relay/delegatecommands on my VM but I can't seem to get my head around the Application commands. I found a couple of old answers but no other information and I am kind of reluctant of following those routes.
This seems like something common but yet informations seems to be very limited. How is this commonly achieved? (With or without using PRISM, MVVM Light, ...)
Old answers:
How to bind ApplicationCommands to a ViewModel but this seems strange to me to solve this using a behavior
WPF - Handle an ApplicationCommand in the ViewModel but I don't think that's MVVM in the accepted answer.
Using attached properties in an old article: CommandBindings with MVVM referencing another article.
It has been a while since I asked this question but it looks like a lot of people are looking at it. I ended up using a behavior which connects the VM command list to the FrameworkElement. This seems to be the most flexible and resusable solution.
public class AttachCommandBindingsBehavior : Behavior<FrameworkElement>
{
public ObservableCollection<CommandBinding> CommandBindings
{
get
{
return (ObservableCollection<CommandBinding>)GetValue(CommandBindingsProperty);
}
set
{
SetValue(CommandBindingsProperty, value);
}
}
public static readonly DependencyProperty CommandBindingsProperty = DependencyProperty.Register("CommandBindings", typeof(ObservableCollection<CommandBinding>), typeof(AttachCommandBindingsBehavior), new PropertyMetadata(null, OnCommandBindingsChanged));
private static void OnCommandBindingsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
AttachCommandBindingsBehavior attachCommandBindingsBehavior = (AttachCommandBindingsBehavior)sender;
if (attachCommandBindingsBehavior == null)
return;
ObservableCollection<CommandBinding> commandBindings = (ObservableCollection<CommandBinding>)e.NewValue;
if (commandBindings != null)
{
if (attachCommandBindingsBehavior.CommandBindings != null)
attachCommandBindingsBehavior.CommandBindings.CollectionChanged -= attachCommandBindingsBehavior.CommandBindings_CollectionChanged;
attachCommandBindingsBehavior.CommandBindings.CollectionChanged += attachCommandBindingsBehavior.CommandBindings_CollectionChanged;
}
}
void CommandBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ObservableCollection<CommandBinding> collection = (ObservableCollection<CommandBinding>)sender;
if (collection != null)
{
foreach (CommandBinding commandBinding in collection)
AssociatedObject.CommandBindings.Add(commandBinding);
}
}
}
In xaml you can then do this:
<i:Interaction.Behaviors>
<localBehaviors:AttachCommandBindingsBehavior CommandBindings="{Binding CommandBindings}"/>
</i:Interaction.Behaviors>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With