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