Sometime I feel some feature is missing but I did not articulated it yet. For example, if I press the "Refresh" button then all the value is refreshed in the DataGrid. It also meant that row selection was cleared.
This was not a major issue because the "Refresh" button is used rarely and I knew that if the ItemsSource of the DataGrid is repopulated then it is natural that there is no SelectedItem.
Later I realized, users may miss the reselect row feature, especially if the "Auto refresh" option is turned on. We need a property to store the id of previously selected row.
int? IdOfThePreviouslySelectedRow { get; set; }
This property is nullable because it has no value if go to a new page.
If CopyDataFromTableVmToDbAsync is called then the new property must be set, so we remember the Id of the selected row.
if (SelectedRow is not null) IdOfThePreviouslySelectedRow = (SelectedRow as IHasId).Id;
If CopyDataFromDbToTableVmAsync is called then the new property is used to reselect the previously selected row.
if (IdOfThePreviouslySelectedRow is not null) { var previouslySelectedRow = DisplayedRows.FirstOrDefault(e => e.Id == IdOfThePreviouslySelectedRow); if (previouslySelectedRow is not null) SelectedRow = previouslySelectedRow; previouslySelectedRow = null; } else selectedRow = null;
The mode was fixed but there was still some problem after the "Refresh" button is used. I was thinking and thinking when I realized the reselection works but the DataGrid is not in focus, so instead of the blue background the light gray background in row six indicated the selection.
public class DataGridGetsFocusAfterSelectionChangedBehavior : Behavior<DataGrid> { protected override void OnAttached() { base.OnAttached(); AssociatedObject.SelectionChanged += OnSelectionChanged; } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.SelectionChanged -= OnSelectionChanged; } private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { var dataGrid = AssociatedObject; if (dataGrid.SelectedItem is null) return; dataGrid.Dispatcher.BeginInvoke(() => dataGrid.Focus()); } }