Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I wanted this for my line-of-business software, and the only way I have found to solve it is by codebehind, using the PreviewKeyDown, GotKeyboardFocus and LostKeyboardFocus events of the datagrid. I have put these eventhandlers in a WPF decorator, to avoid repeating it for every single DataGrid. It would probably be possible to subclass the DataGrid, but I haven't tried that.</p> <p>The code for the handlers are as follows (DataGrid is x:Name="grid" for this sample code):</p> <pre><code> private IInputElement lastDataGridFocus = null; private int selectedcolumnindex = 0; void grid_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { if (grid.Items.Count &gt; 0 &amp;&amp; (e.NewFocus is DataGrid || (e.NewFocus is DataGridCell &amp;&amp; !(e.OldFocus is DataGridCell)))) { DataGridCell cell = null; if (lastDataGridFocus != null) { FocusManager.SetFocusedElement(grid, lastDataGridFocus); lastDataGridFocus = null; e.Handled = true; return; } if (grid.SelectedCells.Count == 0) { DataGridRow rowContainer = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(0); if (rowContainer != null) { DataGridCellsPresenter presenter = GetVisualChild&lt;DataGridCellsPresenter&gt;(rowContainer); cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex &lt; 0) ? 0 : selectedcolumnindex); } } else { DataGridCellInfo selectedDataGridCellInfo = (grid.SelectedCells[0] as DataGridCellInfo?).Value; DataGridRow rowContainer = (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(selectedDataGridCellInfo.Item); if (rowContainer != null) { DataGridCellsPresenter presenter = GetVisualChild&lt;DataGridCellsPresenter&gt;(rowContainer); cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex &lt; 0) ? 0 : selectedcolumnindex); } } if (null != cell) { FocusManager.SetFocusedElement(grid, cell as IInputElement); e.Handled = true; } } } void grid_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { if (!(e.NewFocus is DataGridCell)) { if (grid.CurrentCell != null) { selectedcolumnindex = grid.Columns.IndexOf(grid.CurrentCell.Column); } } } void grid_PreviewKeyDown(object sender, KeyEventArgs e) { if (Keyboard.Modifiers == ModifierKeys.Shift &amp;&amp; e.Key == Key.Tab) { lastDataGridFocus = Keyboard.FocusedElement; grid.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous)); e.Handled = true; } else if (Keyboard.Modifiers == ModifierKeys.None &amp;&amp; e.Key == Key.Tab) { lastDataGridFocus = Keyboard.FocusedElement; grid.MoveFocus(new TraversalRequest(FocusNavigationDirection.Last)); (Keyboard.FocusedElement as FrameworkElement).MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); e.Handled = true; } } </code></pre> <p>With this code you can navigate inside the grid using the cursor keys, and the tab key and shift-tab key gets you out of the datagrid. If you tab out of the grid and come back to the grid, you also get to the same cell that you left. This is what my users and I want, and this is IMHO what the DataGrid control should provide as default behaviour.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload