I want to execute a command when the user selects a row in a DataGrid.
I see it is possible to wrap cell contents in buttons (although I don't want the button style) - but I don't want to do it at the cell-level.
I also see it's possible to use behaviours to link a command to an event. But preferably I should not have to resort to behaviors for such a common task.
Is it possible to do this via plain old command databinding?
So: 1) user clicks DataGrid row 2) command on view model is fired.
You should use "Interactivity" assembly and SelectionChanged
event.
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding People}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" />
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
</DataGrid.Columns>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
Where "i" is namespace:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Also you can write binding to SelectedItem
property of the DataGrid and in the set accessor you can invoke your command, but the first solution that i presented you above is better.
If you want to invoke command from main view model and pass SelectedItem
from DataGrid
you can use CommadParameter
:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}"
CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
When items has own command you can use following code:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding Path=SelectedItem.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Or if elements has own view model that is assigned to it's DataContext
, you can use following code:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding Path=SelectedItem.DataContext.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Be advised that @kmatyaszek's answer is outdated in .NET 5.0 and above, we should use Microsoft.Xaml.Behaviors
instead of Microsoft.Expression.Interactions
.
So the i
in the namespace should be:
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
See here for details.
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