WPF DataGrid: CommandBinding to a double click instead of using Events
Another solution is to add input bindings, and to bind the selectedItem to a property so you'll know which one was selected:
<DataGrid SelectedItem="{Binding SelectedItem}">
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding SomeCommand}"/>
</DataGrid.InputBindings>
</DataGrid>
No need for attached behaviors or custom DataGrid subclasses here.
In your DataGrid
, bind ItemsSource
to an ICollectionView
. The trick here is to set IsSynchronizedWithCurrentItem="True"
which means the selected row will be the current item.
The second part of the trick is to bind CommandParameter
to the current item with the forward slash syntax.
When a row is double clicked, the command will be executed with the clicked row as argument.
<DataGrid
ItemsSource="{Binding CollectionView}"
IsSynchronizedWithCurrentItem="True">
<DataGrid.InputBindings>
<MouseBinding
MouseAction="LeftDoubleClick"
Command="{Binding DoubleClickCommand}"
CommandParameter="{Binding CollectionView/}"/>
</DataGrid.InputBindings>
</DataGrid>
This is how a (simplified) version of the view model would look:
class MyViewModel
{
public ICollectionView CollectionView { get; set; }
public ICommand DoubleClickCommand { get; set; }
}
Use this library
Sample binding to datagrid event:
<DataGrid xmlns:command="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
command:CommandBehavior.Event="MouseDoubleClick"
command:CommandBehavior.Command="{Binding TestCommand}" />
But this code is better, because raises on row clicks only:
<DataGrid>
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Setter Property="command:CommandBehavior.Event" Value="MouseDoubleClick"/>
<Setter Property="command:CommandBehavior.Command" Value="{Binding DataContext.TestCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
</Style>
</DataGrid.Resources>
</DataGrid>
Or, you could create a derived class
public class CustomDataGrid : DataGrid
{
public ICommand DoubleClickCommand
{
get { return (ICommand)GetValue(DoubleClickCommandProperty); }
set { SetValue(DoubleClickCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for DoubleClickCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DoubleClickCommandProperty =
DependencyProperty.Register("DoubleClickCommand", typeof(ICommand), typeof(CustomDataGrid), new UIPropertyMetadata());
public CustomDataGrid()
: base()
{
this.PreviewMouseDoubleClick += new MouseButtonEventHandler(CustomDataGrid_PreviewMouseDoubleClick);
}
void CustomDataGrid_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (DoubleClickCommand != null)
{
DoubleClickCommand.Execute(null);
}
}
}
and in XAML simply bind to the newly created command
<CustomDataGrid DoubleClickCommand="{Binding DoubleClickCommand}">