2
votes

I'm working with VS2015 on a WPF application. On one of my WPF windows, I got a DataGrid with SelectionUnit = Cell and SelectionMode = Single. Furter I got a method to move rows inside the DataGrid up and down for sorting. The sorting works but the problem is that the last cell which was selected by the mouse cursor is visually always selected (blue background), which could disturb the user. So i tried to remove that visual marking of the cell by the following code lines:

datagrid.UnselectAllCells();
datagrid.SelectedCells.Clear();

None of the two lines works for me. The last selected cell is still selected.

How can I remove that selection?

Any help would be appreciated.

At last a snippet from the XAML with the definition of the DataGrid:

<DataGrid x:Name="grdGraphicalElementMatrix" Grid.Row="1" Grid.Column="0"
          HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
          CanUserAddRows="True" 
          IsReadOnly="False"
          AutoGenerateColumns="False"
          SelectionUnit="Cell" SelectionMode="Single"
          CurrentCellChanged="grdGraphicalElementMatrix_CurrentCellChanged"
          ItemsSource="{Binding GraphElemMatrix}">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="colXAssignment"
                            Width="1*"
                            Binding="{Binding Path=X}"
                            Header="X"/>
        <DataGridTextColumn x:Name="colYAssignment"
                            Width="1*"
                            Binding="{Binding Path=Y}"
                            Header="Y"/>
    </DataGrid.Columns>
</DataGrid>

grdGraphicalElementMatrix_CurrentCellChanged is a method in which i can get the selected row and column when the user clicked in one of the cells to select it.

    private void grdGraphicalElementMatrix_CurrentCellChanged(object sender, EventArgs e)
    {
        if (grdGraphicalElementMatrix.CurrentCell != null && grdGraphicalElementMatrix.CurrentCell.Column != null)
        {
            vm.GrdGraphicalElementMatrixSelColIndex = grdGraphicalElementMatrix.CurrentCell.Column.DisplayIndex;
            vm.GrdGraphicalElementMatrixSelRowIndex = grdGraphicalElementMatrix.Items.IndexOf(grdGraphicalElementMatrix.CurrentItem);
        }
    }
2
Are you using the MVVM pattern to bind to your DataGrid? If so I can suggest to bind the SelectedItem property to a property in your model - which you can set to null and it should unselect the item in the grid.Johan Aspeling
@Johan: Hello Johan. Yes i'm using MVVM but i cannot use SelectedItem because of SelectionUnit Cell. SelectedItem would only work with SelectionUnit Row. Isn't it or am i wrong?Patrick Pirzer
Oh I see, the Row selection is not the problem, but rather the individual cell? Which DataGrid are you using?Johan Aspeling
@Johan: I'm using the standard DataGrid of Visual Studio 2015, .NET Framework 4.5.2.Patrick Pirzer
Do you mind adding the xaml of your Datagrid to your question?Johan Aspeling

2 Answers

1
votes

I have set up a testing app which is able to clear the DataGrid Selection - with the following:

View

<DockPanel>
    <Button Content="Clear Selected" DockPanel.Dock="Bottom" Command="{Binding ClearGridCommand}" CommandParameter="{Binding ElementName=datagrid}"/>
    <DataGrid x:Name="datagrid" 
            CurrentCell="{Binding SelectedCell, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            SelectionMode="Single" 
            SelectionUnit="Cell" 
            HorizontalAlignment="Stretch" 
            Margin="10" 
            VerticalAlignment="Stretch" 
            ItemsSource="{Binding Customers}" 
            CanUserAddRows="True" 
            IsReadOnly="False"
            AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name"></DataGridTextColumn>
            <DataGridTextColumn Header="No"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</DockPanel>

Note I am passing the Datagrid through to the Button Command via the CommandParameter

DataContext

private object selectedCell = null;

public object SelectedCell {
    get { return this.selectedCell; }
    set {
        if (this.selectedCell != value) {
            this.selectedCell = value;
            SetPropertyChanged("SelectedCell");
        }
    }
}

public void ClearGrid(object obj) {
    var dg = obj as DataGrid;
    if (dg != null) {
        dg.UnselectAllCells();
    }
}

Maybe you can get more information by debugging the setter in the SelectedCell. Maybe it is clearing, but re-selected through your grdGraphicalElementMatrix_CurrentCellChanged method?

1
votes

Thank You very much for Your help and useful hints. Thanks to You i have found a solution which works.

First i have replaced the CurrentCellChanged-event by the SelectedCellsChanged-event. Then i reprogrammed in the method for moving a selected row up or down. Here the new code for unselecting the cell which is at the old row-index and selecting the cell at the new row-index.

// UnselectAllCells was correct.
datagrid.UnselectAllCells();
// But a refresh is needed. This was missing.
datagrid.Items.Refresh();
// Selects the cell in the moved row. Focus is needed, so the cell appears selected all the time.
datagrid.CurrentCell = new DataGridCellInfo(datagrid.Items[newIndex], datagrid.Columns[GrdGraphicalElementMatrixSelColIndex]);
datagrid.SelectedCells.Add(datagrid.CurrentCell);
datagrid.Focus();