【问题标题】:wpf datagrid mousebinding leftdoubleclick command only works if item already selectedwpf datagrid mousebinding leftdoubleclick 命令仅在已选择项目时才有效
【发布时间】:2017-07-12 07:45:22
【问题描述】:

我有一个 DataGrid 并希望在我的 ViewModel 中定义的命令在我双击一行时执行。这在该行已被选中时有效,但如果我双击当前未选中的行则不起作用,即使我可以看到 DataGrid 的 MouseDoubleClick 事件正在触发并且所需的行已成为 SelectedItem。这是我的 DataGrid 的定义:

<DataGrid Name="ProjectsList" Grid.Row="1" ItemsSource="{Binding FilteredProjects}" VerticalAlignment="Stretch" 
                      HorizontalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False"
                      SelectedItem="{Binding SelectedProject}" PreviewMouseDoubleClick="ProjectsList_PreviewMouseDoubleClick" 
                      MouseDoubleClick="ProjectsList_MouseDoubleClick" >
    <interactivity:Interaction.Behaviors>
        <behaviours:DataGridSelectedProjectsBehaviour SelectedProjects="{Binding SelectedProjects}" />
    </interactivity:Interaction.Behaviors>
    <DataGrid.InputBindings>
        <KeyBinding Key="Delete" Command="{Binding DeleteCommand}" />
        <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding OpenCommand}" />
    </DataGrid.InputBindings>
    <DataGrid.Columns>
        <DataGridTemplateColumn Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid Margin="0,0,8,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>

                        <Rectangle Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Height="2">
                            <Rectangle.Fill>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                    <GradientStop Color="{StaticResource SpruceGreen}" Offset="0" />
                                    <GradientStop Color="{StaticResource DarkGrey}" Offset="0.5" />
                                    <GradientStop Color="{StaticResource LightGrey}" Offset="1" />
                                </LinearGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>
                        <TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding Name}" FontWeight="Bold" />
                        <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding State}" Foreground="Red" HorizontalAlignment="Right" Typography.Capitals="AllSmallCaps" />
                        <TextBlock Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding Created, Converter={StaticResource StringFormat}, ConverterParameter='CREATED {0:dd/MM/yyyy HH:mm}'}" Foreground="Gray" FontSize="10" />
                        <TextBlock Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Text="{Binding Description}" TextWrapping="Wrap" Padding="0,0,0,32" />
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

以下是一些说明问题的日志条目。请原谅我的调试日志条目速记。以 > 结尾的日志条目仅表明调用了该方法([] 中的名称)。 当我双击当前未选中的行时会发生这种情况:

2017/07/12 16:35:52 DEBUG (ThreadId:1) [DataGridSelectedProjectsBehaviour.OnDataGridSelectionChanged] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectViewModel.SelectedCollectionChanged] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectViewModel.get_SelectedTotal] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [DataGridSelectedProjectsBehaviour.ProjectsCollectionChanged] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectViewModel.SelectedCollectionChanged] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectViewModel.get_SelectedTotal] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [DataGridSelectedProjectsBehaviour.ProjectsCollectionChanged] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_PreviewMouseDoubleClick] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_PreviewMouseDoubleClick] - SelectedItem is project [Project2] 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_MouseDoubleClick] - > 
2017/07/12 16:35:52 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_MouseDoubleClick] - SelectedItem is project [Project2] 

当我双击当前选中的一行时会发生这种情况:

2017/07/12 16:35:54 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_PreviewMouseDoubleClick] - > 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_PreviewMouseDoubleClick] - SelectedItem is project [Project2] 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [<Open>d__35.MoveNext] - command was invoked. 
2017/07/12 16:35:54  INFO (ThreadId:1) [BaseViewModel.CheckForUnsavedChanges] - There are no unsaved changes. 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [ProjectSummaryViewModel..ctor] - ViewModel was created. 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [NavigationServiceEx.InternalNavigateTo] - SetParameter finished 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [BaseViewModel.NavigatedFrom] - > 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_MouseDoubleClick] - > 
2017/07/12 16:35:54 DEBUG (ThreadId:1) [SelectProjectPage.ProjectsList_MouseDoubleClick] - SelectedItem is project [Project2] 

如您所见,如果该行已被选中,则会执行 Open 命令。

我曾认为可能是 DataGridSelectedProjectsBehaviour 干扰了 MouseBinding,但是当我删除它时,双击命令永远不会起作用。我真的不需要它并想删除它。它是在预计需要多行选择时添加的。

任何建议将不胜感激。谢谢

【问题讨论】:

    标签: wpf


    【解决方案1】:

    您可以尝试处理 DataGridRow 容器的 MouseDoubleClick 事件,方法是从视图的代码隐藏中调用命令:

    <DataGrid Name="ProjectsList" Grid.Row="1" ItemsSource="{Binding FilteredProjects}" VerticalAlignment="Stretch" 
                          HorizontalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False"
                          SelectedItem="{Binding SelectedProject}" PreviewMouseDoubleClick="ProjectsList_PreviewMouseDoubleClick" 
                          MouseDoubleClick="ProjectsList_MouseDoubleClick" >
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" />
            </Style>
        </DataGrid.RowStyle>
        ...
    </DataGrid>
    

    private void OnItemMouseDoubleClick(object sender, ouseButtonEventArgs e)
    {
        var vm = this.DataContext as YourViewModel;
        vm.YourCommand.Execute(null);
    }
    

    或者通过使用附加行为并基本上做同样的事情:

    <Style TargetType="DataGridRow">
        <Setter Property="local:YourType.YourAttachedCommandProperty" Value="{Binding DataContext.YourCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
    </Style>
    

    【讨论】:

    • 我会考虑这些替代方案,但宁愿弄清楚为什么 MouseBinding 不起作用,因为它是一个更优雅的解决方案。我相信在后面的代码中使用 ViewModel 类型与 MVVM 模式相反,我觉得附加的行为对于已经有如此简单的解决方案的东西来说太过分了。但我确实说过,任何建议都会受到赞赏,而且确实如此。因此,如果我最终使用您的一种解决方案,我会将您标记为答案。谢谢@mm8。
    • 抱歉,我不确定在将回复标记为答案时是否有必要这样做。感谢您的链接。 @mm8
    猜你喜欢
    • 1970-01-01
    • 2020-02-13
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多