First there is some discrepancy in the behaviour written in the question and provided in sample:
I entered some data in first cell of first row and press Enter,
instead of focus moving to second cell of first row, it moves to first
cell of second row.
To fix this issue get rid of this else statement:
else
{
if (ExtractBoundValue(row, dep as DataGridCell) == null
|| ExtractBoundValue(row, dep as DataGridCell).ToString().Trim() == "")
{
return;
}
}
This statement stops second cell to get focus when enter is pressed on first cell of any row.
Now, to your actual problem. Issue is when you press enter on last cell of third row, first cell of fourth row goes into edit mode. Hence, results in creating instance of Person object. Before putting the row in edit mode, first check if row is NewItemPlaceholder
or not.
Replace last line
// start edit mode
maindg.BeginEdit();
with this one which checks for NewItemPlaceholder
and if not then only put row in edit mode:
DependencyObject selectedRow = nextCell;
while ((selectedRow != null) && !(selectedRow is DataGridRow))
{
selectedRow = VisualTreeHelper.GetParent(selectedRow);
}
if ((selectedRow as DataGridRow).Item.ToString() != "{NewItemPlaceholder}")
{
// start edit mode
maindg.BeginEdit();
}
A simpler solution is capture the KeyDown event and if the key is 'Enter', then move to the next tab.
private void dg_PreviewKeyDown(object sender, KeyEventArgs e)
{
var u = e.OriginalSource as UIElement;
if (e.Key == Key.Enter && u != null)
{
e.Handled = true;
u.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
}
}
Best Answer
A much simpler implementation. The idea is to capture the keydown event and if the key is "Enter", then move to the next tab which is next cell of the grid.