Ответ, данный Гауссом , является правильным подходом, но с некоторым кодом он более ясен:
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;
}
Вы извлекаете строку в событии DataGrid.LoadingRow
, но ячейка еще не доступна. Таким образом, вы помещаете обработчик в событие Loaded
, чтобы дождаться его возникновения, а затем можете извлечь ячейку и сфокусироваться на ней.
Обработчик удален, чтобы избежать нового запуска.
Сессия редактирования также может быть запущена с dataGrid.BeginEdit()
.
Все это в коде, потому что оно принадлежит представлению.