I know this is a fairly old question, but I ran into the same problem today and wasn't too interested in referencing all of MVVMLight just so I can use event triggers with event args. I have used MVVMLight in the past and it's a great framework, but I just don't want to use it for my projects any more.
What I did to resolve this problem was create an ULTRA minimal, EXTREMELY adaptable custom trigger action that would allow me to bind to the command and provide an event args converter to pass on the args to the command's CanExecute and Execute functions. You don't want to pass the event args verbatim, as that would result in view layer types being sent to the view model layer (which should never happen in MVVM).
Here is the EventCommandExecuter class I came up with:
public class EventCommandExecuter : TriggerAction<DependencyObject> { #region Constructors public EventCommandExecuter() : this(CultureInfo.CurrentCulture) { } public EventCommandExecuter(CultureInfo culture) { Culture = culture; } #endregion #region Properties #region Command public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(EventCommandExecuter), new PropertyMetadata(null)); #endregion #region EventArgsConverterParameter public object EventArgsConverterParameter { get { return (object)GetValue(EventArgsConverterParameterProperty); } set { SetValue(EventArgsConverterParameterProperty, value); } } public static readonly DependencyProperty EventArgsConverterParameterProperty = DependencyProperty.Register("EventArgsConverterParameter", typeof(object), typeof(EventCommandExecuter), new PropertyMetadata(null)); #endregion public IValueConverter EventArgsConverter { get; set; } public CultureInfo Culture { get; set; } #endregion protected override void Invoke(object parameter) { var cmd = Command; if (cmd != null) { var param = parameter; if (EventArgsConverter != null) { param = EventArgsConverter.Convert(parameter, typeof(object), EventArgsConverterParameter, CultureInfo.InvariantCulture); } if (cmd.CanExecute(param)) { cmd.Execute(param); } } } }
This class has two dependency properties, one to allow binding to your view model's command, the other allows you to bind the source of the event if you need it during event args conversion. You can also provide culture settings if you need to (they default to the current UI culture).
This class allows you to adapt the event args so that they may be consumed by your view model's command logic. However, if you want to just pass the event args on verbatim, simply don't specify an event args converter.
The simplest usage of this trigger action in XAML is as follows:
<i:Interaction.Triggers> <i:EventTrigger EventName="NameChanged"> <cmd:EventCommandExecuter Command="{Binding Path=Update, Mode=OneTime}" EventArgsConverter="{x:Static c:NameChangedArgsToStringConverter.Default}"/> </i:EventTrigger> </i:Interaction.Triggers>
If you needed access to the source of the event, you would bind to the owner of the event
<i:Interaction.Triggers> <i:EventTrigger EventName="NameChanged"> <cmd:EventCommandExecuter Command="{Binding Path=Update, Mode=OneTime}" EventArgsConverter="{x:Static c:NameChangedArgsToStringConverter.Default}" EventArgsConverterParameter="{Binding ElementName=SomeEventSource, Mode=OneTime}"/> </i:EventTrigger> </i:Interaction.Triggers>
(this assumes that the XAML node you're attaching the triggers to has been assigned x:Name="SomeEventSource"
This XAML relies on importing some required namespaces
xmlns:cmd="clr-namespace:MyProject.WPF.Commands" xmlns:c="clr-namespace:MyProject.WPF.Converters" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
and creating an IValueConverter (called NameChangedArgsToStringConverter in this case) to handle the actual conversion logic. For basic converters I usually create a default static readonly converter instance, which I can then reference directly in XAML as I have done above.
The benefit of this solution is that you really only need to add a single class to any project to use the interaction framework much the same way that you would use it with InvokeCommandAction. Adding a single class (of about 75 lines) should be much more preferable to an entire library to accomplish identical results.
NOTE
this is somewhat similar to the answer from @adabyron but it uses event triggers instead of behaviours. This solution also provides an event args conversion ability, not that @adabyron's solution could not do this as well. I really don't have any good reason why I prefer triggers to behaviours, just a personal choice. IMO either strategy is a reasonable choice.