I have a datagrid in which I want my Enter key to work like TAB key. So, I followed this post.
After following that post's accepted answer, I got the required functionality. But there I get a small problem.
When I press Enter on last cell of the last row of the DataGrid, a new row is added to the datagrid but the last cell of the newly added row is focused instead of first cell.
What I want is when I press enter on the last cell of the last row, a new row should be added and the first cell of the newly created row should be focused instead of last cell.
Note : Above problem occurs only when a new row is added to the datagrid. While navigating through existing rows it works as expected.
Mainly I have used 4 files in this sample project.
Person.cs
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
}
MainWindowViewModel.cs
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
People = new ObservableCollection<Person>();
}
private ObservableCollection<Person> _people;
public ObservableCollection<Person> People
{
get
{
return _people;
}
set
{
_people = value;
OnPropertyChanged("People");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<DataGrid x:Name="maindg" AutoGenerateColumns="True"
ItemsSource="{Binding People}"
PreviewKeyDown="DataGrid_KeyDown_1" SelectedIndex="0"
GridLinesVisibility="Vertical"
SelectionMode="Single" SelectionUnit="CellOrRowHeader">
</DataGrid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DataGrid_KeyDown_1(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;
DependencyObject dep = (DependencyObject)e.OriginalSource;
//here we just find the cell got focused ...
//then we can use the cell key down or key up
// iteratively traverse the visual tree
while ((dep != null) && !(dep is DataGridCell) && !(dep is DataGridColumnHeader))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
if (dep is DataGridCell)
{
//cancel if datagrid in edit mode
maindg.CommitEdit();
//get current cell
DataGridCell cell = dep as DataGridCell;
//deselect current cell
cell.IsSelected = false;
//find next right cell
var nextCell = cell.PredictFocus(FocusNavigationDirection.Right);
//if next right cell null go for find next ro first cell
if (nextCell == null)
{
DependencyObject nextRowCell;
nextRowCell = cell.PredictFocus(FocusNavigationDirection.Down);
//if next row is null so we have no more row Return;
if (nextRowCell == null) return;
//we do this because we cant use FocusNavigationDirection.Next for function PredictFocus
//so we have to find it this way
while ((nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left) != null)
nextRowCell = (nextRowCell as DataGridCell).PredictFocus(FocusNavigationDirection.Left);
//set new cell as next cell
nextCell = nextRowCell;
}
//change current cell
maindg.CurrentCell = new DataGridCellInfo(nextCell as DataGridCell);
//change selected cell
(nextCell as DataGridCell).IsSelected = true;
// start edit mode
maindg.BeginEdit();
}
//handl the default action of keydown
e.Handled = true;
}
}
I have not posted the Styling code for simplicity purposes.