You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM模式下自动生成列的DataGrid双击事件实现咨询

实现MVVM风格的DataGrid单元格双击功能

Absolutely! You can absolutely add a double-click interaction (and keep it MVVM-friendly by using commands instead of code-behind events) to your auto-generated column DataGrid. Here are two clean, compliant approaches tailored to your setup:

方案1:使用Blend行为(最快捷)

This method leverages Microsoft's XAML behaviors package to bind the double-click event directly to a ViewModel command. First, install the Microsoft.Xaml.Behaviors.Wpf NuGet package if you haven't already.

Update your DataGrid XAML to include the trigger:

<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="OnAutoGeneratingColumn" 
          CanUserSortColumns="False" GridLinesVisibility="None" 
          CanUserAddRows="False" SelectionUnit="Cell" 
          ItemsSource="{Binding ValuesView}" 
          CellStyle="{StaticResource CellStyle}" 
          CurrentCell="{Binding SelectedValue, Mode=TwoWay}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding CellDoubleClickCommand}" 
                                   CommandParameter="{Binding CurrentCell, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>

Then define the command in your ViewModel (using a standard RelayCommand implementation—you can write your own or use one from an MVVM framework like Prism/MvvmLight):

public ICommand CellDoubleClickCommand { get; }

public YourViewModel()
{
    CellDoubleClickCommand = new RelayCommand<DataGridCellInfo>(ExecuteCellDoubleClick);
}

private void ExecuteCellDoubleClick(DataGridCellInfo cellInfo)
{
    if (cellInfo.IsValid && cellInfo.Item is DataRowView rowView)
    {
        // Access the clicked cell's value using the column's sort member path
        var cellValue = rowView[cellInfo.Column.SortMemberPath];
        // Add your business logic here (e.g., open a detail view, edit the value)
    }
}

方案2:自定义附加属性(无外部依赖)

If you prefer not to add external packages, create a custom attached property to handle the double-click and bind it to your command:

First, create the static extension class:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

public static class DataGridCellDoubleClick
{
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(DataGridCellDoubleClick),
            new PropertyMetadata(null, OnCommandChanged));

    public static void SetCommand(DependencyObject element, ICommand value)
    {
        element.SetValue(CommandProperty, value);
    }

    public static ICommand GetCommand(DependencyObject element)
    {
        return (ICommand)element.GetValue(CommandProperty);
    }

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is DataGrid dataGrid)
        {
            dataGrid.MouseDoubleClick -= DataGrid_MouseDoubleClick;
            if (e.NewValue is ICommand command)
            {
                dataGrid.MouseDoubleClick += (s, args) =>
                {
                    // Find the clicked cell in the visual tree
                    if (args.OriginalSource is DependencyObject depObj)
                    {
                        var cell = depObj.FindVisualParent<DataGridCell>();
                        if (cell != null && dataGrid.CurrentCell.IsValid)
                        {
                            command.Execute(dataGrid.CurrentCell);
                        }
                    }
                };
            }
        }
    }

    // Helper method to traverse the visual tree
    private static T FindVisualParent<T>(this DependencyObject child) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(child);
        return parent is T parentT ? parentT : parent?.FindVisualParent<T>();
    }
}

Then attach it to your DataGrid in XAML:

<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="OnAutoGeneratingColumn" 
          CanUserSortColumns="False" GridLinesVisibility="None" 
          CanUserAddRows="False" SelectionUnit="Cell" 
          ItemsSource="{Binding ValuesView}" 
          CellStyle="{StaticResource CellStyle}" 
          CurrentCell="{Binding SelectedValue, Mode=TwoWay}"
          local:DataGridCellDoubleClick.Command="{Binding CellDoubleClickCommand}"/>

Your ViewModel command logic stays identical to the first approach.

Key Notes

  • Since your ItemsSource is a DataTable view, the cell's Item will be a DataRowView—make sure to cast it correctly when accessing values.
  • With SelectionUnit="Cell", passing CurrentCell as the command parameter gives you precise access to the clicked cell's context.

内容的提问来源于stack exchange,提问作者Wojciech Szabowicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:27:49