WPF DataGrid:命令绑定到双击而不是使用事件

WPF DataGrid:命令绑定到双击而不是使用事件,wpf,datagrid,double-click,commandbinding,Wpf,Datagrid,Double Click,Commandbinding,我知道如何在DataGrid中使用MouseDoubleClick事件来获取selectedvalue,但是如何使用命令绑定呢?这样我的ViewModel就可以处理逻辑了 到目前为止,我有以下几点: <DataGrid Name="TestGrid" Grid.Row="2" Grid.ColumnSpan="2" AutoGenerateColumns="True" MouseDoubleClick="TestGrid_MouseDoubleClick" ItemsS

我知道如何在DataGrid中使用MouseDoubleClick事件来获取selectedvalue,但是如何使用命令绑定呢?这样我的ViewModel就可以处理逻辑了

到目前为止,我有以下几点:

<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">

我想去掉鼠标双击并适当地更换它。

使用

绑定到datagrid事件的示例:

<DataGrid xmlns:command="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
    command:CommandBehavior.Event="MouseDoubleClick"
    command:CommandBehavior.Command="{Binding TestCommand}" />

但这段代码更好,因为只在行单击时引发:

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

或者,您可以创建一个派生类

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);
        }
    }


}
在XAML中,只需绑定到新创建的命令

<CustomDataGrid DoubleClickCommand="{Binding DoubleClickCommand}">

另一种解决方案是添加输入绑定,并将selectedItem绑定到属性,以便您知道选择了哪个:

<DataGrid SelectedItem="{Binding SelectedItem}">
      <DataGrid.InputBindings>
          <MouseBinding Gesture="LeftDoubleClick" Command="{Binding SomeCommand}"/>
     </DataGrid.InputBindings>
</DataGrid>

此处不需要附加行为或自定义DataGrid子类

DataGrid
中,将
ItemsSource
绑定到
ICollectionView
。这里的技巧是设置
IsSynchronizedWithCurrentItem=“True”
,这意味着所选行将是当前项

技巧的第二部分是使用正斜杠语法将
CommandParameter
绑定到当前项

双击一行时,将以单击的行作为参数执行命令

<DataGrid
    ItemsSource="{Binding CollectionView}"
    IsSynchronizedWithCurrentItem="True">
    <DataGrid.InputBindings>
        <MouseBinding
            MouseAction="LeftDoubleClick"
            Command="{Binding DoubleClickCommand}"
            CommandParameter="{Binding CollectionView/}"/>
    </DataGrid.InputBindings>
</DataGrid>

我喜欢这个图书馆,但它似乎包含了比我需要的更多的东西(目前)。我将查看库,如果我需要的不仅仅是双击命令,那么可能这将包含我不介意使用的其他命令。@myermian您也可以查看MVVM Light,它有类似的类和其他类,有助于使用MVVM模式。对我来说,添加对库的引用比复制代码更容易,但使用第三方库还是编写自己的库是一个有争议的问题。您的
{Binding CollectionView/}
中的
/
是故意的吗?是的,这使它绑定到当前项。与
IsSynchronizedWithCurrentItem一起使用时,表示所选项目。一篇博客文章。非常简洁的解决方案。也不知道正斜杠绑定。有时候我真的很惊讶人们从哪里知道这种事情。非常感谢。这是一个很好的解决方案。但这里有一个缺点。如果双击DataGrids的头,该命令仍将执行。在某些场景中,这可能是开发人员不希望看到的事情。如何解决这个问题?请注意,如果DataGrid的
IsReadOnly=“False”
,则第一次单击可能会被选择机制窃取。设置
IsReadOnly=“True”
来解决这个问题。很好,很优雅。很好,但有一个问题。假设您有一个具有多列的datagrid,并且最后一列未设置为width=*并且您在最后一列之后的额外空间中双击最右侧,所选项目将不会更新,并且它将传递所选项目之前的任何内容。如果所选项目不存在,它将通过null。您是否检查了此项,提供了完整的解决方案。。。
class MyViewModel
{
    public ICollectionView CollectionView { get; set; }

    public ICommand DoubleClickCommand { get; set; }
}