DoubleClick 在 DataGrid 和 DataTemplate 中触发

DoubleClick fired both in DataGrid and DataTemplate

长话短说;我在网格中有一个网格。两个网格都有双击事件,应该触发不同的方法调用(主网格显示 window,而 DataTemplate 中的网格显示 window,其中包含来自所选详细信息行的参数)。

问题是即使 e.Handled 设置为 true,双击详细信息行也会调用双击主网格。

笨蛋 XAML:

<Window x:Class="DoubleClickDataTemplate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DoubleClickDataTemplate"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <DataTemplate x:Key="LinesGrid">
            <DataGrid x:Name="dgLines" 
                        ItemsSource="{Binding Path=Lines}" 
                        AutoGenerateColumns="True" 
                        IsReadOnly="True"
                        MouseDoubleClick="dgLines_MouseDoubleClick">
            </DataGrid>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="dgFiles" 
                    ItemsSource="{Binding}" 
                    AutoGenerateColumns="True" 
                    IsReadOnly="True"
                    RowDetailsVisibilityMode="VisibleWhenSelected"
                    RowDetailsTemplate="{StaticResource LinesGrid}" 
                    MouseDoubleClick="dgFiles_MouseDoubleClick">
        </DataGrid>
    </Grid>
</Window>

简化的源文件:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace DoubleClickDataTemplate
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<FileClass> files = new List<FileClass>();
            files.Add(new FileClass() { FileName = "File1", Lines = new List<LineClass>() { new LineClass() { LineNumber = 1, LineContents = "F1L1 contents" }, new LineClass() { LineNumber = 2, LineContents = "F1L2 contents" } } });
            files.Add(new FileClass() { FileName = "File2", Lines = new List<LineClass>() { new LineClass() { LineNumber = 1, LineContents = "F2L1 contents" }, new LineClass() { LineNumber = 2, LineContents = "F2L2 contents" } } });
            dgFiles.ItemsSource = files;
        }

        private void dgFiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("dgFiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)");
        }

        private void dgLines_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("dgLines_MouseDoubleClick(object sender, MouseButtonEventArgs e)");
            e.Handled = true;
        }
    }

    public class FileClass
    {
        public string FileName { get; set; }
        public List<LineClass> Lines { get; set; }
    }

    public class LineClass
    {
        public int LineNumber { get; set; }
        public string LineContents { get; set; }
    }
}

输出显示,当我在 DataTemplate/DetailRow:

中双击时,两个事件都会被调用
00:05.616 (00:03:456) dgLines_MouseDoubleClick(object sender, MouseButtonEventArgs e)
                      dgFiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)

最接近 "solution" 的是使用锁定标志 (https://www.oipapio.com/question-3430969),但这在很多方面都可能出错。

有没有办法让双击详情行只调用相关事件而不是同时调用两个事件?

您可以处理 MouseLeftButtonDown 并检查 ClickCount 以获得外部 DataGrid:

private void dgFiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    if (e.ClickCount == 2)
    {
        System.Diagnostics.Debug.WriteLine("dgFiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)");
    }
}


private void dgLines_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    System.Diagnostics.Debug.WriteLine("dgLines_MouseDoubleClick(object sender, MouseButtonEventArgs e)");
    e.Handled = true;
}

XAML:

<Window.Resources>
    <DataTemplate x:Key="LinesGrid">
        <DataGrid x:Name="dgLines" 
                ItemsSource="{Binding Path=Lines}" 
                AutoGenerateColumns="True" 
                IsReadOnly="True"
                MouseDoubleClick="dgLines_MouseDoubleClick">
        </DataGrid>
    </DataTemplate>
</Window.Resources>
<Grid>
    <DataGrid x:Name="dgFiles" 
            ItemsSource="{Binding}" 
            AutoGenerateColumns="True" 
            IsReadOnly="True"
            RowDetailsVisibilityMode="VisibleWhenSelected"
            RowDetailsTemplate="{StaticResource LinesGrid}" 
            MouseLeftButtonDown="dgFiles_MouseDoubleClick">
    </DataGrid>
</Grid>