web-dev-qa-db-fra.com

WPF DataGrid: CommandBinding à un double-clic au lieu d'utiliser des événements

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.

29
m-y

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; }
}
66
Mizipzor

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>
23
Tamar Cohen

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>
2
vortexwolf

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}">
1
Catalin Pop