0
votes

I have a DataGrid and want a command, defined in my ViewModel, to execute when I double click on a row. This works when the row is already selected, but doesn't if I double click on a row that is not currently selected, even though I can see that the DataGrid's MouseDoubleClick event is firing and the required row has become the SelectedItem. Here is the definition of my 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>

Here are some log entries that demonstrate the problem. Please excuse my Debug log entry shorthand. Log entries ending with > just indicate that the method (name in []) was called. This is what happens when I double click on a row that is not currently selected:

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] 

This is what happens when I double click on a row when it is currently selected:

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] 

As you can see, the Open command is executed if the row is already selected.

I had thought that possibly the DataGridSelectedProjectsBehaviour was interfering with the MouseBinding, but when I remove it, the double click command never works. I don't really need it and would like to remove it. It was added when it was expected that multi-row selection was required.

Any suggestions would be much appreciated. Thanks

1

1 Answers

1
votes

You could try to handle the MouseDoubleClick event for the DataGridRow container, either by invoking the command from the code-behind of the view:

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

Or by using an attached behaviour and basically do the same thing:

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