只有在单击DataGrid行时才执行WPF MouseDoubleClick事件

5
我在WPF中有一个DataGrid。当我双击一行时,应该执行对数据库的查询。
这个DataGrid有水平和垂直滚动条,我注意到当我快速点击其中一个滚动条的箭头按钮时,它会发送查询到数据库。
问题在于,我正在使用DataGrid的MouseDoubleClick事件,所以滚动条属于DataGrid,当它们被双击时,这个事件就会被触发。
是否有办法只在我双击DataGrid的行时才执行双击事件,而不是在双击滚动条的某个部分时执行?
2个回答

8
在您的MouseDoubleClick事件中,请尝试执行以下操作:
private void DataGridMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    DependencyObject src = VisualTreeHelper.GetParent((DependencyObject)e.OriginalSource);

    // Checks if the user double clicked on a row in the datagrid [ContentPresenter]
    if (src.GetType() == typeof(ContentPresenter))
    {
        // Your logic..
    }
}

我认为这不会起作用。DataGrid 中有许多 ContentPresenter(不仅仅是行),而且您无法确定 ContentPresenter 是否是 e.OriginalSource 的直接父级。 - LPL
我以前使用过这种方法并取得了成功。关键是,如果e.OriginalSource的直接父级是ContentPresenter,则可以假定用户单击了该行或该行中某个列中的对象,因此您可以获取所选行。如果它是其他东西,比如Border或Grid,请忽略它。您有任何可能出错的示例吗? - Eirik
我还没有尝试过。这只是我的想法。我的意思是ContentPresenter并不表示一行。那么它真的不会在ColumnHeaders和ScrollBars上触发吗?如果模板不是默认的,那又怎么办? - LPL
列标题的父级是网格(Grid),滚动条(ScrollBar)可以是重复按钮(RepeatButton)或拇指(Thumb)。我猜你可能可以编辑模板来使用这种方法产生不期望的结果,但我确定你可以相应地进行调整?我还没有能够使它失败,但我不知道这种方法是否万无一失。如果不是,我想知道 :) - Eirik
ContentPresenter不起作用(在DataGrid中有许多ContentPresenter,例如Headers) - Xilmiki
@Xilmiki 为了消除标题中的 ContentPresenter,只需检查 ContentPresenter 的可视父级是否为 DataGridHeaderBorder。如果是,则忽略该命中。 - Eirik

7

是的,在RowStyle中注册事件。

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <EventSetter Event="PreviewMouseDoubleClick" Handler="Row_PreviewMouseDoubleClick" />
    </Style>
</DataGrid.RowStyle>

在数据网格中为每一行添加事件设置器的开销是多少? - Mark
我认为没有什么可说的,因为所有行只有一个处理程序实例。 - LPL
1
干得好!运行良好,我没有看到任何性能降低(关于Mark问的问题)。 - B.K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接