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; } |
Login