EventToCommand Action – MVVM Glue

One of my favourite additions to WPF is the Blend Interactivity library which allows you to decorate behaviour into controls in XAML. This really is the glue that allows you to work around MVVM problems in third-party libraries or the framework itself.

The following is an example of a Trigger and Action, to bind SelectedItems to a ViewModel as it changes. This work around is required as SelectedItems isn’t bindable.

<ListBox Name="ItemsToChoose">
  <i:Interaction.Triggers>
    <!-- Can't bind directly to Selected Items 😦 -->
    <i:EventTrigger EventName="SelectionChanged">
      <Command:ChangePropertyOnTarget
          Target="{Binding}" PropertyName="SelectedItems"
          Value="{Binding SelectedItems, ElementName=ItemsToChoose}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox

One of the most common scenarios for me is the need to execute a command when a control raises a particular event. For instance double-clicking an item in a ListView. The MVVM Light Toolkit has  a great TriggerAction called EventToCommand which has been a great help, allowing me to redirect an event and turn it into a command as such:

<ListBox Name="list">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
      <Command:EventToCommand
           Command="{Binding Path=DataContext.DoSomethingCommand,ElementName=list}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

There are two small short-comings with the original. Firstly that it provides no access to the EventArgs. I have tweaked the original to add an EventArgs which you can use in your bindings of the command parameter. (Source Here)

This example shows the tweaked EventToCommand, passing in the DataContext of the clicked row.

<ListBox Name="list">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
      <Command:EventToCommand
           Command="{Binding Path=DataContext.DoSomethingCommand,ElementName=list}"
 CommandParameter="{Binding EventArgs.OriginalSource.DataContext, RelativeSource={RelativeSource Self}}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

I have also rectified the second issue; it doesn’t implement ICommandSource so it does not handle RoutedCommands.

Advertisements
Tagged , , ,

6 thoughts on “EventToCommand Action – MVVM Glue

  1. Kenji says:

    EventToCommand has a property called PassEventArgsToCommand(bool) which does what ya want. -k

  2. Anonymous says:

    This passes the whole EventArgs to the command. This allows you to bind an property on EventArgs to your commandparameter so you don’t need to couple your command to an event.

    It also implements ICommandSource.

  3. Catherine says:

    This should implement exactly what I need, but I can’t get it to recognise EventArgs and the parameter is passed across as null. Is there anything extra I need to do to implement the EventArgs part in xaml?

  4. adammills says:

    Shouldn’t be, which event on which control are you trying to capture?

    • Catherine says:

      It’s the MouseRightButtonDown event on a DataGrid. I get BindingExpression path error: ‘EventArgs’ property not found on ‘object’ ”EventToCommand’. I guess I should change the implementation for a DataGrid but I’m not that familiar with XAML

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: