I have a data grid with few text columns and a Delete button:
<DataGrid ItemsSource="{Binding Customers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="False" SelectedItem="{Binding SelectedCustomer}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}">
<DataGridTextColumn.Header>
<Label Content="{DynamicResource FirstName}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding LastName}">
<DataGridTextColumn.Header>
<Label Content="{DynamicResource LastName}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Address}">
<DataGridTextColumn.Header>
<Label Content="{DynamicResource Address}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{DynamicResource Delete}" Command="{Binding DeleteCustomerCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding SelectedCustomer, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Having read this question and answer:
How to use RelativeSource Binding to create DataGrid binding to Model and ViewModel?
I addded the
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}
part. However, nothing works still. When I debug with Snoop, I can see DataContexts are properly set. The datacontext of the DataGrid
is the ViewModel, and it uses the Customers
collection property, and the data context of the grid rows are the individual Customer
objects, which is expected.
I have checked that commands are referred to with their real names and that they're public. Command is initialized in the ViewModel's constructor:
DeleteCustomerCommand = new RelayCommand<Customer>(DeleteCustomer);
and the Commands are public properties with private setters:
public RelayCommand<Customer> DeleteCustomerCommand { get; private set; }
I only get the following error:
DeleteCustomerCommand' property not found on 'object' ''DataGrid' (Name='')'. BindingExpression:Path=DeleteCustomerCommand; DataItem='DataGrid' (Name=''); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')
Try add "DataContext" to your command binding:
Command="{Binding DataContext.DeleteCustomerCommand, RelativeSource=...
because there is no DeleteCustomerCommand
property on your DataGrid
but in the view model connected with the DataGrid
.
Additional info
Sometimes it helps me to create a binding for a DataContext
with the Visual Studio assistant instead of coding it completely by hand.
Just look for the property you want to create a binding for in the property grid of the control.
In this case its the Command
property. Left click on the text box for the command property text, then choose "Create data binding..." from the context menu.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With