Je sais comment utiliser l'événement MouseDoubleClick avec mon DataGrid pour récupérer la valeur sélectionnée, mais comment utiliser à la place les liaisons de commandes? De cette façon, mon ViewModel peut gérer la logique.
Jusqu'à présent, j'ai les éléments suivants:
<DataGrid Name="TestGrid" Grid.Row="2" Grid.ColumnSpan="2" AutoGenerateColumns="True" MouseDoubleClick="TestGrid_MouseDoubleClick"
ItemsSource="{Binding Registrations}" SelectedValue="{Binding CurrentRegistration}" IsReadOnly="True" AlternationCount="2" GridLinesVisibility="None">
Je veux me débarrasser de MouseDoubleClick et le remplacer de manière appropriée.
Pas besoin de comportements attachés ou de sous-classes DataGrid personnalisées ici.
Dans votre DataGrid
, liez ItemsSource
à un ICollectionView
. L'astuce consiste à définir IsSynchronizedWithCurrentItem="True"
ce qui signifie que la ligne sélectionnée sera l'élément actuel.
La deuxième partie de l'astuce consiste à lier CommandParameter
à l'élément actuel avec la syntaxe de barre oblique.
Lorsqu'une ligne est double-cliquée, la commande sera exécutée avec la ligne cliquée comme argument.
<DataGrid
ItemsSource="{Binding CollectionView}"
IsSynchronizedWithCurrentItem="True">
<DataGrid.InputBindings>
<MouseBinding
MouseAction="LeftDoubleClick"
Command="{Binding DoubleClickCommand}"
CommandParameter="{Binding CollectionView/}"/>
</DataGrid.InputBindings>
</DataGrid>
Voici à quoi ressemblerait une version (simplifiée) du modèle de vue:
class MyViewModel
{
public ICollectionView CollectionView { get; set; }
public ICommand DoubleClickCommand { get; set; }
}
Une autre solution consiste à ajouter des liaisons d'entrée et à lier le selectedItem à une propriété afin que vous sachiez laquelle a été sélectionnée:
<DataGrid SelectedItem="{Binding SelectedItem}">
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding SomeCommand}"/>
</DataGrid.InputBindings>
</DataGrid>
Utilisez cette bibliothèque
Exemple de liaison à un événement de grille de données:
<DataGrid xmlns:command="clr-namespace:AttachedCommandBehavior;Assembly=AttachedCommandBehavior"
command:CommandBehavior.Event="MouseDoubleClick"
command:CommandBehavior.Command="{Binding TestCommand}" />
Mais ce code est meilleur, car n'augmente que les clics sur les lignes:
<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>
Ou, vous pouvez créer une classe dérivée
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);
}
}
}
et en XAML simplement se lier à la commande nouvellement créée
<CustomDataGrid DoubleClickCommand="{Binding DoubleClickCommand}">