0
votes

I'm trying to implement multiple selection for DataGrid and I want to be able to unselect row by clicking on it again. I defined datagrid like this:


<DataGrid 
                  Style="{StaticResource DefaultDataGrid}" 
                  IsReadOnly="True" 
                  CanUserAddRows="False"
                  AutoGenerateColumns="False"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  SelectionMode="Extended"
                  CurrentCell="{Binding CellInfo, Mode=OneWayToSource}"
                  ItemsSource="{Binding TestCases}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="PreviewMouseDown">
                            <i:InvokeCommandAction Command="{Binding DataGridClickCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <DataGrid.RowStyle>
                        <Style TargetType="DataGridRow">
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="WhiteSmoke" />
                                </Trigger>
                                <DataTrigger Binding="{Binding IsChecked}" Value="True">
                                    <Setter Property="Background" Value="{StaticResource SelectedCellBackgroundBlueBrush}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGrid.RowStyle>
                    <DataGrid.Columns>
                        <DataGridCheckBoxColumn Width="40" ElementStyle="{StaticResource DataGridCheckBox}" Binding="{Binding IsChecked}">
                            <DataGridCheckBoxColumn.Header>
                                <CheckBox HorizontalAlignment="Center" Style="{StaticResource DefaultCheckBox}" />
                            </DataGridCheckBoxColumn.Header>
                        </DataGridCheckBoxColumn>
                        <DataGridTextColumn Header="Test Case Id" Binding="{Binding Id}" />
                        <DataGridCheckBoxColumn Width="60" Header="Derived?" Binding="{Binding IsDerived}" ElementStyle="{StaticResource ReadOnlyCheckBox}"/>
                        <DataGridTextColumn Header="Title" Binding="{Binding Title}" />
                        <DataGridTextColumn Header="Parameters File" Binding="{Binding ParameterFile}" />
                        <DataGridTemplateColumn Width="50" Header="Valid">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Image HorizontalAlignment="Left" Source="../Icons/ok-icon-green.png" Width="15" Height="15"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTemplateColumn Width="50" Header="Result">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Image HorizontalAlignment="Left" Source="../Icons/ok-icon-green.png" Width="15" Height="15" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>

And my ViewModel looks like


        private ICommand _dataGridClickCommand;
        public ICommand DataGridClickCommand
        {
            get
            {
                if (_dataGridClickCommand == null)
                {
                    _dataGridClickCommand = new RelayCommand(() => DataGridClick());
                }

                return _dataGridClickCommand;
            }
        }

        private void DataGridClick()
        {

        }

        private TreeModel _treeModel;
        private CancellationTokenSource _cancellationToken;

        public ObservableCollection<TestTreeData> TestSuites { get; set; }

        public ObservableCollection<TestCaseViewModel> TestCases { get; }

        public ObservableCollection<TestCaseViewModel> SelectedTestCases { get; }

        private DataGridCellInfo _cellInfo;
        public DataGridCellInfo CellInfo
        {
            get => _cellInfo;
            set
            {
                _cellInfo = value;
                OnPropertyChanged("CellInfo");
            }
        }

But I find out that then you click on already selected row the CurrentCell or SelectionChanged events not raised. I tried to bind command on click on datagrid to unselect selected row but as I see CurrentCell event raised after click event and I can't handle which row was clicked. Does anybody know how to do this? Thank you

1
What you want is already a feature of the DataGrid. Anyway, this is view logic and doesn't belong to the view model. Either handle the events in code-behind or create a behavior or extend the DataGrid class.BionicCode

1 Answers

0
votes

In order to de-select a row using SelectionMode="Extended", the user must use CTRL + Click.

Like @BionicCode mentioned, If you want a different behavior you'll need to create an attached/XAML behavior or extend the DataGrid control with new functionality. Both of these options will not be easy to do.

I would just use the default CTRL + Click behavior as it's a universal windows standard for extended multi-select.