WPF DataGrid: CommandBinding to a double click instead of using Events

前端 未结 4 1244
轮回少年
轮回少年 2021-02-01 02:37

I know how to use the MouseDoubleClick event with my DataGrid to grab the selectedvalue, but how would one go about using command bindings instead? That way my ViewModel can han

相关标签:
4条回答
  • 2021-02-01 03:02

    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>
    
    0 讨论(0)
  • 2021-02-01 03:14

    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; }
    }
    
    0 讨论(0)
  • 2021-02-01 03:16

    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>
    
    0 讨论(0)
  • 2021-02-01 03:26

    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}">
    
    0 讨论(0)
提交回复
热议问题