5

I am using WPF DataGrid row deletion by keyboard "Delete" key press. However, after the row is deleted, DataGrid lost its focus, and DataGrid.SelectedIndex = -1.

Compared to WinForm datagrid, after a row is deleted, the focus automatically shift to the next focusable row, which is much more reasonable.

By "next focusable", I mean, e.g.:

Row A
Row B
Row C

If we delete Row A, the next focusable will be Row B.
If we delete Row B, the next focusable will be Row C.
If we delete Row C, the next focusable will be Row B (the last row).

How can we achieve the same effect in WPF datagrid?

By the way, the following is an example that focuses on the first row after deletion, which is not ideal, since we wanted it to be the "next focusable row".

    private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.RemovedItems.Count > 0)
        {
            DataGrid grid = sender as DataGrid;
            if (grid.SelectedIndex == -1)
            {
                grid.SelectedCells.Clear();
                grid.SelectedIndex = 0;
            }
        }
    }

Any ideas?

Thanks.

RainCast
  • 4,134
  • 7
  • 33
  • 47
  • `DataGrid` doesn't looses focus, deleted row (item) does. And to implement *behavior* (which is not default) you have to do some work, e.g.: disable deleting, manually process key presses, handle `Delete` key to delete row/rows and apply behavior you want. – Sinatr Mar 10 '15 at 12:25
  • How do you fill your `DataGrid`? Is it by binding it's ItemsSource? – Tomtom Mar 10 '15 at 12:29
  • @Sinatr I can't manually handle, I did keybinding for delete for some reason. – RainCast Mar 10 '15 at 12:36
  • @Tomtom, yes, the ItemsSource did bind to data defined in ViewModel, and the DataGrid is editable. – RainCast Mar 10 '15 at 12:37
  • Then the `DataGrid` does automatically set the focus to the next row – Tomtom Mar 10 '15 at 12:38
  • @Tomtom, really? at least to me it didn't... – RainCast Mar 11 '15 at 04:50

1 Answers1

1

What are you binding your DataGrid to? Have you tried a CollectionView (MSDN)? That has props like CurrentPosition and the MoveCurrentToNext() method. You could get the current position of the row being deleted and then locate the next one based on the sort order of the CollectionView.

Update: If you're doing MVVM, disable the DataGrid's delete (see this answer) and have your VM remove the item from the collection. You'll know which item is being removed so you should then be able to figure out what the next (or prior) item is. Have your VM expose a SelectedItem property which you'll bind to the DataGrid.SelectedItem. Set the SelectedItem on your VM and the row should be selected in the DataGrid.

It sounds like the WinForms Datagrid handled a lot of this out of the box so you probably feel like you're reinventing the wheel and that this is a lot of work for something that just worked automatically in the "old" UX technology.

Community
  • 1
  • 1
KornMuffin
  • 2,887
  • 3
  • 32
  • 48
  • "get the current position of the row being deleted ", yeah, I am trying to, but is there an easy way to pass it out? – RainCast Mar 11 '15 at 07:40
  • I am binding it to an IObservableCollection. – RainCast Mar 11 '15 at 07:40
  • The Collection View (https://msdn.microsoft.com/en-us/library/system.windows.data.collectionview%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) helps with navigating a data collection. ObservableCollection give you notifications when the collection changes which doesn't help with navigation. I'll update my answer with some more info. – KornMuffin Mar 11 '15 at 12:32
  • The row will be *selected* but not **focused** those are two quite distinct DataGridRow states. – wondra Jan 15 '20 at 14:53