MVVMlight button in DataTemplate

For a major project I’m currently working on I needed to add a button to the items in a ListPicker. This projects uses MVVMLight as MVVM framework, so I have to use the RelayCommand for the handling of the button clicks. My initial thought was to do it just like any other button:

View (XAML):

<button content="Action" width="200">
<phone:PhoneApplicationPage.Resources>
  <datatemplate x:key="ActionTemplate">
    <stackpanel orientation="Horizontal"> 
      <textblock width="450" textwrapping="Wrap" margin="0" text="{Binding ActionName}" />  
      <button content="Use" width="200">
        <custom:interaction.triggers>
          <custom:eventtrigger eventname="Click">
	    <galasoft_mvvmlight_command:eventtocommand command="{Binding ActionCommand, Mode=OneWay}" />
          </custom:eventtrigger>
        </custom:interaction.triggers>
      </button>
    </stackpanel>
  <datatemplate />
</phone:PhoneApplicationPage.Resources>

ViewModel:

public RelayCommand ActionCommand
{
  get;
  private set;
}
//Constructor
public LogonViewModel()
{
  this.ActionCommand = new RelayCommand(() => this.DoAction());
}
public object DoAction()
{
  //Some action
  return null
}

But that didn’t work, the relaycommand was never executed. The reason is obvious, the datacontext of the ListPickerItem, and thus the DataTemplate, isn’t the ViewModel, it’s the item itself. How to solve this problem? That is quit simple. The ViewModel and the View needs only a small adjustment:

<phone:PhoneApplicationPage.Resources>
  <ContentControl x:Key="Context" Content="{Binding}" />
  <datatemplate x:key="ActionTemplate">
    <stackpanel orientation="Horizontal"> 
      <textblock width="450" textwrapping="Wrap" margin="0" text="{Binding ActionName}" />  
      <button content="Use" width="200">
        <custom:interaction.triggers>
          <custom:eventtrigger eventname="Click">
	    <galasoft_mvvmlight_command:eventtocommand Command="{Binding DataContext.ActionCommand, Mode=OneWay, Source={StaticResource Context}}" CommandParameter="{Binding}"/>
          </custom:eventtrigger>
        </custom:interaction.triggers>
      </button>
    </stackpanel>
  <datatemplate />
</phone:PhoneApplicationPage.Resources>
public RelayCommand<Action> ActionCommand
{
  get;
  private set;
}
//Constructor
public LogonViewModel()
{
  this.ActionCommand = new RelayCommand<Action>(a => this.DoAction(a));
}
public object DoAction(Action a)
{
  // "a" contains the item which button was pressed
  //Some action
  return null;
}

Comments are closed.