Author : Admin
Last Modified : 22-Mar-2022
Complexity : Intermediate

Interactive Command: How can we pass Event Argument to a command in the View Model from XAML


Interactivity is used for handling/accessing the event in ViewModel instead of directly using it in code-behind. This article is not about what is Interactivity and how do we listen and handle the events in the ViewModel code. 

With Interactivity, we can access the event in Viewmodel but still, we have the issue of passing the event arguments. In MVVM we can not get the event argument directly.

In the below implementation we will see how we can get the event argument in ViewModel.

Step 1

Add the reference of  System.Windows.Interactivity.dll in the application.

Step 2

Add the class InteractiveCommand inherit from TriggerAction<DependencyObject>.

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace InteractivityHelper
{
   public class InteractiveCommand : TriggerAction<DependencyObject>
   {
       protected override void Invoke(object parameter)
       {
           if (base.AssociatedObject != null)
           {
               ICommand command = this.ResolveCommand();
               if ((command != null) && command.CanExecute(parameter))
               {
                   command.Execute(parameter);
               }
           }
       }
       
       private ICommand ResolveCommand()
       {
           ICommand command = null;
           if (this.Command != null)
           {
               return this.Command;
           }
           if (base.AssociatedObject != null)
           {
               foreach (PropertyInfo info in base.AssociatedObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
               {
                   if (typeof(ICommand).IsAssignableFrom(info.PropertyType) && string.Equals(info.Name, this.CommandName, StringComparison.Ordinal))
                   {
                       command = (ICommand)info.GetValue(base.AssociatedObject, null);
                   }
               }
           }
           return command;
       }
       
       private string commandName;
       public string CommandName
       {
           get
           {
               base.ReadPreamble();
               return this.commandName;
           }
           set
           {
               if (this.CommandName != value)
               {
                   base.WritePreamble();
                   this.commandName = value;
                   base.WritePostscript();
               }
           }
       }
       #region Command
       public ICommand Command
       {
           get { return (ICommand)GetValue(CommandProperty); }
           set { SetValue(CommandProperty, value); }
       }
       // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
       
       public static readonly DependencyProperty CommandProperty =
           DependencyProperty.Register("Command", typeof(ICommand), typeof(InteractiveCommand), new UIPropertyMetadata(null));
           
       #endregion
   }
}

Step 3

Add the XAML file 

<Window x:Class="InteractivityEventArgsDemo.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="MainWindow" Height="350" Width="525"
       xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
       xmlns:IntractComm="clr-namespace:InteractivityHelper">
   <Grid>
       <TextBox Height="23" HorizontalAlignment="Left" Margin="124,63,0,0" Name="TextBox1"
                Text="" VerticalAlignment="Top" Width="200">
           <i:Interaction.Triggers>
               <i:EventTrigger EventName="TextChanged">
                   <IntractComm:InteractiveCommand Command="{Binding CommandWithEventArgs}"/>
               </i:EventTrigger>
           </i:Interaction.Triggers>
       </TextBox>
   </Grid>
</Window>

Step 4

 In the ViewModel, we define the command that will execute as text changes.

using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;

namespace InteractivityEventArgsDemo
{
   public class MainWindowVM
   {
       #region CommandWithEventArgs
       
       DelegateCommand<TextChangedEventArgs> _CommandWithEventArgs;
       
       /// <summary>
       /// Exposes <see cref="CommandWithEventArgs(MouseEventArgs)"/>.
       /// </summary>
       public DelegateCommand<TextChangedEventArgs> CommandWithEventArgs
       {
           get { return _CommandWithEventArgs ?? (_CommandWithEventArgs = new 		DelegateCommand<TextChangedEventArgs>(TextBoxTextChanged)); }
       }
       
       #endregion

       private void TextBoxTextChanged(TextChangedEventArgs e)
       {
           //some processimg
       }
   }
}

Download 

Interactivity assembly