The default behavior of DataGrid
is to move down when pressing Enter
key. I'm trying to change that to move to Right
.
I have seen this and have tried to implement it as below. It is kinda working and the it is moving one column to the right when pressing Enter
key but it is also moving one row down!
For instance when I'm on cell containing 55
and press enter, I end up on cell containing 20
.
I have debugged it but doesn't seem to find what the problem is. The value of the cell is correct in cell.Focus();
and I don't know what happens after that causes this. The odd part is it works when I'm on the last row and press enter.
------------------
| Depth | Width |
------------------
| 55 | 30 |
------------------
| 45 | 20 |
------------------
private void PreviewKeyDown(object sender, KeyEventArgs e)
{
var grid = (DataGrid)sender;
if (e.Key == Key.Enter || e.Key == Key.Return)
{
var columnIndex = grid.Columns.IndexOf(MyDataGrid.CurrentColumn);
var rowIndex = grid.Items.IndexOf(MyDataGrid.CurrentItem);
// index of the next column
columnIndex = columnIndex + 1;
// reset column index if we are at the end of the row
if (columnIndex > grid.Columns.Count - 1)
{
rowIndex = rowIndex + 1;
columnIndex = 0;
// return if we have reached the last row
if (rowIndex > grid.Items.Count - 1)
{
return;
}
}
// there should always be a selected cell
if (grid.SelectedCells.Count != 0)
{
SelectCellByIndex(grid, rowIndex, columnIndex);
}
}
}
public static void SelectCellByIndex(DataGrid dataGrid, int rowIndex, int columnIndex)
{
if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.CellOrRowHeader))
throw new ArgumentException("The SelectionUnit of the DataGrid must be set to Cell.");
if (rowIndex < 0 || rowIndex > (dataGrid.Items.Count - 1))
throw new ArgumentException(string.Format("{0} is an invalid row index.", rowIndex));
if (columnIndex < 0 || columnIndex > (dataGrid.Columns.Count - 1))
throw new ArgumentException(string.Format("{0} is an invalid column index.", columnIndex));
dataGrid.SelectedCells.Clear();
object item = dataGrid.Items[rowIndex]; //=Product X
DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
if (row == null)
{
dataGrid.ScrollIntoView(item);
row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
}
if (row != null)
{
DataGridCell cell = GetCell(dataGrid, row, columnIndex);
if (cell != null)
{
DataGridCellInfo dataGridCellInfo = new DataGridCellInfo(cell);
dataGrid.SelectedCells.Add(dataGridCellInfo);
cell.Focus();
}
}
}
public static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
{
if (rowContainer != null)
{
DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
if (presenter == null)
{
/* if the row has been virtualized away, call its ApplyTemplate() method
* to build its visual tree in order for the DataGridCellsPresenter
* and the DataGridCells to be created */
rowContainer.ApplyTemplate();
presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
}
if (presenter != null)
{
DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
if (cell == null)
{
/* bring the column into view
* in case it has been virtualized away */
dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
}
return cell;
}
}
return null;
}
public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
return (T)child;
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}