在WPF DataGrid中捕获鼠标双击

时间:2018-03-30 06:20:06

标签: c# wpf datagrid

我需要能够在我的DataGrid中的MouseDoubleClick事件上运行命令,但是由于单击启动的单元格编辑功能,事件似乎从未进入网格,即使我有一个只读网格。

这是一个答案,讨论覆盖winforms数据网格上的编辑功能,但我无法在Windows控件数据网格上找到相同的内容。

MouseDoubleClick event is not fired when a cell is double-clicked in System.Windows.Forms.DataGrid

我可以一起完成编辑,尽管我希望尽可能保留它。我确实需要在某些时候添加编辑功能,但它只会通过点击每一行上的编辑按钮来激活,所以如果我需要以某种方式编辑覆盖,我可以让按钮打开一个覆盖,允许他们输入行值而不是直接将它们输入网格。

<DataGrid Grid.Row="1" Margin="0,0,0,0"  VerticalScrollBarVisibility="Auto" BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1"
                                  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" x:Name="AdvancedGrid" IsReadOnly="True"
                                  ItemsSource="{Binding FolderCollection, NotifyOnSourceUpdated=True}" SelectionMode="Extended"
                                  AutoGenerateColumns="False" CanUserDeleteRows="False" CanUserAddRows="False" CanUserResizeRows="True" 
                                  CanUserResizeColumns="True" CanUserSortColumns="True" CanUserReorderColumns="True" SelectedItem="{Binding LastSelectedItemAdvanced, Mode=TwoWay}"
                                    dataGridFilterLibrary:DataGridExtensions.ProcessIsInEditMode="True"

                                    dataGridFilterLibrary:DataGridExtensions.UseBackgroundWorkerForFiltering="True"

                                    dataGridFilterLibrary:DataGridExtensions.IsClearButtonVisible="False"

                                    dataGridFilterLibrary:DataGridExtensions.IsFilterVisible="True"

                                    ColumnHeaderStyle="{StaticResource {ComponentResourceKey 
                                            TypeInTargetAssembly={x:Type dataGridFilterLibrary:DataGridHeaderFilterControl}, 
                                            ResourceId=DataGridHeaderFilterControlStyle}}"
                                  >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <command:EventToCommand Command="{Binding OpenFolderCommand}" AlwaysInvokeCommand="True" CommandParameter="{Binding ElementName=SelectedItemBox, Path=SelectedItem}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        <DataGrid.Columns>
                <DataGridTextColumn Width="*" MinWidth="125" Header="Folder Name"
                                    Binding="{Binding Name}"
                                    >

                </DataGridTextColumn>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=DataContext.Name, RelativeSource={RelativeSource Self}}"></TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

解决方案更新04/12/18

我将下面的答案标记为最佳选项(截至目前唯一的选项),因为它将我带到了我的答案,这非常相似,只是不那么脏。

在试图弄清楚为什么提供的解决方案没有遇到同样的问题时,事件没有被解雇,我注意到它使用了附加到单元格的样式。因此,只要您在单元格中查找它们,似乎仍然可以捕获DataGrid的鼠标单击。知道这些信息就不需要使用&#34; PreviewMouseLeftButtonDown&#34;使用脏代码后面的方法来计算点击次数。如果&#34; PreviewMouseLeftButtonDown&#34;然后点击&#34; PreviewMouseDoubleClick&#34;事件也应该开火。

XAML:

<DataGrid>
    <DataGrid.Resources>
        <Style TargetType="DataGridCell">
            <EventSetter Event="PreviewMouseDoubleClick" Handler="DataGridCell_PreviewMouseDoubleClick"></EventSetter>
        </Style>
    </DataGrid.Resources>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged" >
            <command:EventToCommand Command="{Binding UpdateSelectedItemsCommand, Mode=OneWay}" AlwaysInvokeCommand="True" CommandParameter="{Binding ElementName=FolderGrid, Path=SelectedItems}"  />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <DataGrid.Columns>
        <DataGridTextColumn Width="*" MinWidth="125" Header="Folder Name"
                                    Binding="{Binding Name}"
                                    >
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

代码背后:

private async void DataGridCell_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var datacontext = this.DataContext as PublicFolderGridViewModel;

    if (datacontext?.LastSelectedFolder?.Identity != null)
    {
        await datacontext.LoadChildFoldersAsync(datacontext.LastSelectedFolder);
    }
}

另一方面,这是我在整个项目期间唯一一次为视图创建代码的代码。所以这是文件背后唯一的代码,代码隐藏文件中唯一的东西就是双击处理程序。如果有人可以告诉我如何在没有使用MVVM背后的代码的情况下实现这一点,请随时详细说明。

1 个答案:

答案 0 :(得分:0)

这有点棘手,因为(正如您所注意到的)点击数据网格已经有了意义。我想你需要一些代码。 我整理了一个实验来探索这一点。 我的代码是:

 <DataGrid.Resources>
    <Style TargetType="DataGridCell">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"/>
    </Style>
</DataGrid.Resources>

private async void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    rowClickCount++;
    await Task.Delay(200);
    if (rowClickCount ==2)
    {
        rowClickCount = 0;
        MessageBox.Show("Invoke command");
    }
    rowClickCount = 0;
}

这当然有点快速和肮脏...但作为概念证明确定。 我得到了消息框,当它触发时,我的行将是当前/选定的行,所以我可以调用一个命令并依赖它来决定双击哪个项目。

如果您想逐列应用该列,您可以通过使用键创建一个样式并在每列上设置cellstyle来实现:

<DatagridTextColumn ..... CellStyle="{StaticResource doubleClickStyle}"