【问题标题】:WPF DataGrid: CommandBinding to a double click instead of using EventsWPF DataGrid:CommandBinding 双击而不是使用事件
【发布时间】:2011-04-22 01:23:04
【问题描述】:

我知道如何在我的 DataGrid 中使用 MouseDoubleClick 事件来获取选定的值,但是如何改用命令绑定呢?这样我的 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">

我想去掉 MouseDoubleClick 并适当地替换它。

【问题讨论】:

  • 你检查过这个post,提供完整的解决方案...

标签: wpf datagrid double-click commandbinding


【解决方案1】:

这里不需要附加行为或自定义 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>

这是视图模型的(简化)版本的外观:

class MyViewModel
{
    public ICollectionView CollectionView { get; set; }

    public ICommand DoubleClickCommand { get; set; }
}

【讨论】:

  • 你的/ 是故意在{Binding CollectionView/} 中的吗?
  • 是的,这使它绑定到当前项目。与IsSynchronizedWithCurrentItem 一起使用时,表示选中的项目。 Here's 一篇博文。
  • 非常简洁的解决方案。也不知道正斜杠绑定。有时我真的很惊讶人们从哪里知道这种事情。谢谢!
  • 这是一个很好的解决方案。但这里有一个缺点。如果双击 DataGrids 的标题,则无论如何都会执行该命令。在某些情况下,这对开发人员来说可能是不受欢迎的事情。怎么解决呢?
  • 注意,如果IsReadOnly="False"为你的DataGrid,那么第一次点击可能会被盗取选择机制。设置IsReadOnly="True" 来解决这个问题。
【解决方案2】:

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

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

【讨论】:

  • 美观大方。
  • 很好,但有一个问题。假设您有一个包含多列的数据网格,并且最后一列未设置为 width=* 并且您在最后一列之后的额外空间中双击最右侧,所选项目将不会更新,它将传递所选项目之前的任何内容.如果不存在选定的项目,它将传递 null。
【解决方案3】:

使用this library

绑定到数据网格事件的示例:

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

【讨论】:

  • 我喜欢这个库,但它似乎包含的内容超出了我的需要(目前)。我会看一下库,如果我需要的不仅仅是双击命令,那么也许这将包含我不介意的其他命令。
  • @myermian 你也可以看看 MVVM Light,它有类似的类和其他有助于使用 MVVM 模式的类。对我来说,添加对库的引用比复制代码更容易,但是是使用 3rd 方库还是编写自己的库是一个有争议的问题。
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2016-05-11
    • 2019-02-09
    • 2021-04-21
    • 2021-11-12
    • 2010-11-05
    相关资源
    最近更新 更多