Focus on DataGridCell for SelectedItem when DataGrid gets keyboard focus

I have a DataGrid where the SelectedItem bound to the VM property Selected. I have a search control that will search and SelectedItem the DataGrid changes (and scrolls in the view). WPF 4.0 and DataGrid SelectionUnit="FullRow" .

My focus problem. DataGrid gets focus (via an attached property / binding), but you cannot use the Up , Down , Page Up , Page Down keys to change rows ( SelectedItem ). If I click again, the first cell of the first row is selected, which changes the SelectedItem .

On the bottom line, how can I adjust the keyboard focus on the DataGridCell for SelectedItem when the DataGrid gets focus?

There are so many DataGrid / Focus questions and have already tried several times. Thank you for your help.

+6
source share
3 answers

You need to specify the just selected logical focus of the row. After selecting a new item, try replacing the SetFocus call as follows:

  var selectedRow = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(dataGrid1.SelectedIndex); FocusManager.SetIsFocusScope(selectedRow, true); FocusManager.SetFocusedElement(selectedRow, selectedRow); 
+7
source

This PowerShell snippet worked for me:

 $dataGrid = ... $dataGrid.add_GotKeyboardFocus({ param($Sender,$EventArgs) if ($EventArgs.OldFocus -isnot [System.Windows.Controls.DataGridCell) { $row = $dataGrid.ItemContainerGenerator.ContainerFromIndex($dataGrid.SelectedIndex) $row.MoveFocus((New-Object System.Windows.Input.TraversalRequest("Next"))) } }) 
0
source

The FocusManager solution for some reason did not work. I also needed a more general approach. So here is what I came up with:

 using System.Windows.Controls; public static void RestoreFocus(this DataGrid dataGrid, int column = 0, bool scrollIntoView = false) { if (dataGrid.IsKeyboardFocusWithin && dataGrid.SelectedItem != null) { // make sure everything is up to date dataGrid.UpdateLayout(); if (scrollIntoView) { dataGrid.ScrollIntoView(dataGrid.SelectedItem); } var cellcontent = dataGrid.Columns[column].GetCellContent(dataGrid.SelectedItem); var cell = cellcontent?.Parent as DataGridCell; if (cell != null) { cell.Focus(); } } } 

And name it as follows:

 MyDataGrid.IsKeyboardFocusWithinChanged += (sender, e) => { if ((bool)e.NewValue == true) { Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() => { MyDataGrid.RestoreFocus(scrollIntoView: true); })); } }; 
0
source

Source: https://habr.com/ru/post/947341/


All Articles