I have a datagrid bound to an observable collection. When the user press the "add button" it adds a new row and I do this by adding a new element to the observablecollection.
I cannot figure out how to make the newly added row with the first cell in focus as if we were editing. I am using a MVVM pattern.
Any ideas or suggestions?
The answer given by Gauss is the right 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 an handler on the Loaded
event in order to wait for this event to occur and then you can retrieve the cell and put the focus on it.
The handler is removed to avoid a new triggering.
The editing session can also be started with dataGrid.BeginEdit()
.
All of this is in the code-behind, because it belongs to the view.
Try capturing the DataGrid's LoadingRow
(or similar) event. Do a SetFocus(e.Row)
(or similar) on the row. This is purely View-oriented, so it conforms to MVVM.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With