【问题标题】:Capture Mouse Double Click in WPF DataGrid在 WPF DataGrid 中捕获鼠标双击
【发布时间】:2018-03-30 06:20:06
【问题描述】:

我需要能够在我的 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 的鼠标单击。知道该信息后,无需将“PreviewMouseLeftButtonDown”与计算点击次数的脏代码隐藏方法一起使用。如果“PreviewMouseLeftButtonDown”触发,那么“PreviewMouseDoubleClick”事件也应该触发。

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 来实现这一点,请随时详细说明。

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    这有点棘手,因为(如您所见)单击数据网格已经有意义。我认为您将需要一些代码。 我做了一个实验来探索这个。 我的有效代码是:

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

    这当然有点快和肮脏......但可以作为概念证明。 我打开消息框,在触发时,我的行将是当前/选定的行,因此我可以调用命令并依靠它来决定双击哪个项目。

    如果您想逐列应用该列,您可以通过将其设为带有键的样式并在每列上设置单元格样式,大致如下:

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

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 2013-05-08
      • 2010-12-11
      • 2014-04-24
      • 1970-01-01
      • 2014-11-05
      • 2010-12-10
      • 2012-12-24
      • 2011-09-25
      相关资源
      最近更新 更多