Gauss's answer is the correct approach, but with some code it is clearer:
void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.Loaded += Row_Loaded; } void Row_Loaded(object sender, RoutedEventArgs e) { var row = (DataGridRow) sender; row.Loaded -= Row_Loaded; DataGridCell cell = GetCell(dataGrid, row, 0); if (cell != null) cell.Focus(); dataGrid.BeginEdit(); } static DataGridCell GetCell(DataGrid dataGrid, DataGridRow row, int column) { if (dataGrid == null) throw new ArgumentNullException("dataGrid"); if (row == null) throw new ArgumentNullException("row"); if (column < 0) throw new ArgumentOutOfRangeException("column"); DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(row); if (presenter == null) { row.ApplyTemplate(); presenter = FindVisualChild<DataGridCellsPresenter>(row); } if (presenter != null) { var cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell; if (cell == null) { dataGrid.ScrollIntoView(row, dataGrid.Columns[column]); cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell; } return cell; } return null; } static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); var visualChild = child as T; if (visualChild != null) return visualChild; var childOfChild = FindVisualChild<T>(child); if (childOfChild != null) return childOfChild; } return null; }
You retrieve the row in the DataGrid.LoadingRow event, but the cell is not yet available. So you put a handler in the Loaded event to wait for this event to occur, and then you can get the cell and direct it to it.
The handler is deleted to avoid a new start.
An edit session can also be started using dataGrid.BeginEdit() .
All of this is in code because it belongs to the view.
Maxence
source share