GalaSoft_MvvmLight_Command:EventToCommand on a button on a ListItem?
What is the syntax for hooking up a mvvm-light EventToCommand on a line item in a data template? For an action on the main model, syntax like the below works fine, however if I am doing an operation on a line item in a data template, the binding isn't working, and I need to identify the specific line item to operate on.
Before attempting to hook up the Event to Command I had the line item click hooked to an event handler in the XAML codebehind; the handler extracted the line item data object out of the event args, and then passed the line item data object to a method via the DataContext to the view model and that worked fine, but I wanted to stay consistent with handling across the app.
Runtime error in output: System.Windows.Data Error: BindingExpression path error: 'EditLineCommand' property not found on 'Model.LineItem'. BindingExpression: Path='EditLineCommand' DataItem='Model.LineItem'; target element is 'System.Windows.Controls.Button' (Name='EditRowButton'); target property is 'DependencyPropertyListener39' (type 'System.Object')..
XAML main layout:
<!-- Line Items -->
<ListBox ItemTemplate="{StaticResource LineItemTemplate}" ItemsSource="{Binding Model.LineItems}"/>
XAML data template:
<DataTemplate x:Key="LineItemTemplate">
<Button>
<Image Source="..." />
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding EditLineCommand, Mode=OneWay}" />
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
</DataTemplate>
Update - I think I'm almost there, @Claus' answer got me most of the way by solving the Command binding problem. To identify the specific line to operate on, I bind to the LineNumber of the LineItem and then pull that parameter out on the relay command:
<GalaSoft_MvvmLight_Command:EventToCommand
Command="{Binding DataContext.DeleteLineCommand, ElementName=DetailPage}"
CommandParameter="{Binding LineNumber}"
PassEventArgsToCommand="True" />
...
public RelayCommand<int> DeleteLineCommand { get; private set; }
...
DeleteLineCommand = new RelayCommand<int>((ln) => { DeleteLineItem(ln); });
This is a workable solution, but is there a way to bind to the full LineItem rather than开发者_Go百科 just a member?
See Bind datagrid to one ViewModel, column / combobox to another for a discussion on how to bind to a property (or command) of a view model from a data template.
Magic trick:
<phone:PhoneApplicationPage x:Name="MyPage" ... >
...
<GalaSoft_MvvmLight_Command:EventToCommand
Command="{Binding DataContext.EditLineCommand, ElementName=MyPage}" />
...
</phone:PhoneApplicationPage>
That way, it'll use the Page's DataContext, which usually is your ViewModel.
精彩评论