Prism Commands - binding error when binding to list element?
I've got a ItemsControl (to be replaced by listbox) which has it's ItemsSource bound to an ObservableCollection<User>
which is located in the view model.
The View Model contains some DelegateCommand<T>
delegates for handling commands (for instance UpdateUserCommand and RemoveUserCommand). All works fine if the buttons linked to those commands are placed outside of the DataTemplate of the control which is presenting the items.
<ItemsControl ItemsSource="{Binding Users, Mode=TwoWay}" HorizontalContentAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.2*"/>
开发者_JAVA百科 <ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding UserName}"/>
<PasswordBox Grid.Column="1" Password="{Binding UserPass}"/>
<TextBox Grid.Column="2" Text="{Binding UserTypeId}"/>
<Button Grid.Column="3" Content="Update" cal:Click.Command="{Binding UpdateUserCommand}" cal:Click.CommandParameter="{Binding}"/>
<Button Grid.Column="4" Content="Remove" cal:Click.Command="{Binding RemoveUserCommand}" cal:Click.CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What I'm trying to achieve, is : Have each row - generated by the ListView/ItemsControl - contain buttons to manage the item represented that particular row.
During the runtime, the VS's output panel generated the following messages for each listbox element
System.Windows.Data Error: BindingExpression path error: 'UpdateUserCommand' property not found on 'ModuleAdmin.Services.User' 'ModuleAdmin.Services.User' (HashCode=35912612). BindingExpression: Path='UpdateUserCommand' DataItem='ModuleAdmin.Services.User' (HashCode=35912612); target element is 'System.Windows.Controls.Button' (Name=''); target property is 'Command' (type 'System.Windows.Input.ICommand')..
System.Windows.Data Error: BindingExpression path error: 'RemoveUserCommand' property not found on 'ModuleAdmin.Services.User' 'ModuleAdmin.Services.User' (HashCode=35912612). BindingExpression: Path='RemoveUserCommand' DataItem='ModuleAdmin.Services.User' (HashCode=35912612); target element is 'System.Windows.Controls.Button' (Name=''); target property is 'Command' (type 'System.Windows.Input.ICommand')..
Which would imply that there are binding errors present.
Is there any way to make this right? or is this not the way?
The DataTemplate gets its DataContext explicitly set to the item the template is representing. That is to say, your DataTemplate's DataContext would be a User object, not the ViewModel that contains the ObservableCollection. The way your commands are being bound, it's expecting to find the commands on the User object.
You can explicitly set the binding source or you can override the data context.
<ItemsControl HorizontalContentAlignment="Stretch" ItemsSource="{Binding Users, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
...
<Button
Grid.Column="3"
cal:Click.Command="{Binding UpdateUserCommand, Source={StaticResource myVM}}"
cal:Click.CommandParameter="{Binding}"
Content="Update"/>
<Button
Grid.Column="4"
cal:Click.Command="{Binding RemoveUserCommand, Source={StaticResource myVM}}"
cal:Click.CommandParameter="{Binding}"
Content="Remove"/>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
精彩评论