Invoking commands from events using the InvokeCommandAction behavior

MVVM is something for me. Databinding your data and behavior so you don’t have any code in your views is for me a nice separation of concepts. However some control’s cannot execute a command for certain events, for example when you select something in a listbox.

Enters InvokeCommandAction, which is a behavior which allows you to invoke a command when a certain event occurs. You can find it beneath Blend’s 4 behaviors:

image

You can attach this behavior to any control, and then select which command to execute when an event occurs. Let’s use a simple ListBox with strings example:

<Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:viewModels="clr-namespace:CommandsAndEvents"
       xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" x:Class="CommandsAndEvents.Window1"
       Title="Window1" Height="300" Width="300">
  <Window.DataContext>
    <viewModels:ListViewModel />
  </Window.DataContext>
    <Grid>
    <ListBox x:Name="listBox" ItemsSource="{Binding Names}" >
    </ListBox>
  </Grid
>
</
Window
>

This window will show a list of names from the following ListViewModel:

public class ListViewModel
{
 
public
ListViewModel()
  {
    Names =
new ObservableCollection<string> { "Jan", "Piet", "Joris", "Corneel"
};
    SelectionChangedCommand =
    
new RelayCommand("Test", (item) => ShowSelected((string
)item)); // string is the type of the selected item
  }

 
public ObservableCollection<string> Names { get; set
; }



 
public ICommand SelectionChangedCommand { get; set
; }


 
private void ShowSelected(string
item)
  {
   
MessageBox.Show(item);
  }
}

Now, if I’d like the ListBox to call the SelectionChangedCommand I simply add the following behavior:

<ListBox x:Name="listBox" ItemsSource="{Binding Names}" >
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
 
                            
CommandParameter="{Binding SelectedItem, ElementName=listBox}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

 

Notice that this allows for arguments to be passed to the command, which then allows you access to any property on the control!