将焦点移动到输入键上的下一个单元格按WPF DataGrid?

我想要一个可以的Custom DataGrid,

  1. 如果处于编辑模式,当按下Enter键时也移动到下一个单元格。
  2. 当达到当前行中的最后一列时,焦点应移动到下一行的第一个单元格。
  3. 在到达下一个单元格时,如果单元格是可编辑的,它应该自动变为可编辑。
  4. 如果单元格包含ComboBox而不是combobox,则combobox应该是DropDownOpen。

请帮帮我。 我在过去的几天里一直在尝试创建一个Custom DataGrid并编写了一些代码

 protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e) 

但我失败了。

 private void dg_PreviewKeyDown(object sender, KeyEventArgs e) { try { if (e.Key == Key.Enter) { e.Handled = true; var cell = GetCell(dgIssuance, dgIssuance.Items.Count - 1, 2); if (cell != null) { cell.IsSelected = true; cell.Focus(); dg.BeginEdit(); } } } catch (Exception ex) { MessageBox(ex.Message, "Error", MessageType.Error); } } public static DataGridCell GetCell(DataGrid dg, int row, int column) { var rowContainer = GetRow(dg, row); if (rowContainer != null) { var presenter = GetVisualChild(rowContainer); if (presenter != null) { // try to get the cell but it may possibly be virtualized var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); if (cell == null) { // now try to bring into view and retreive the cell dg.ScrollIntoView(rowContainer, dg.Columns[column]); cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); } return cell; } } return null; } 

一个更简单的实现。 想法是捕获keydown事件,如果键是“Enter”,则移动到下一个选项卡,该选项卡是网格的下一个单元格。

 ///  /// On Enter Key, it tabs to into next cell. ///  ///  ///  private void DataGrid_OnPreviewKeyDown(object sender, KeyEventArgs e) { var uiElement = e.OriginalSource as UIElement; if (e.Key == Key.Enter && uiElement != null) { e.Handled = true; uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } } 
 public class DataGrid : System.Windows.Controls.DataGrid { private void PressKey(Key key) { KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key); args.RoutedEvent = Keyboard.KeyDownEvent; InputManager.Current.ProcessInput(args); } protected override void OnCurrentCellChanged(EventArgs e) { if (this.CurrentCell.Column != null) if (this.CurrentCell.Column.DisplayIndex == 2) { if (this.CurrentCell.Item.ToString() == "--End Of List--") { this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); } } else if (this.CurrentCell.Column != null && this.CurrentCell.Column.DisplayIndex == this.Columns.Count() - 1) { PressKey(Key.Return); DataGridCell cell = DataGridHelper.GetCell(this.CurrentCell); int index = DataGridHelper.GetRowIndex(cell); DataGridRow dgrow = (DataGridRow)this.ItemContainerGenerator.ContainerFromItem(this.Items[index]); dgrow.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); } } protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.Enter) { DataGridRow rowContainer = (DataGridRow)this.ItemContainerGenerator.ContainerFromItem(this.CurrentItem); if (rowContainer != null) { int columnIndex = this.Columns.IndexOf(this.CurrentColumn); DataGridCellsPresenter presenter = UIHelper.GetVisualChild(rowContainer); if (columnIndex == 0) { DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next); request.Wrapped = true; cell.MoveFocus(request); BeginEdit(); PressKey(Key.Down); } else { CommitEdit(); DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next); request.Wrapped = true; cell.MoveFocus(request); } this.SelectedItem = this.CurrentItem; e.Handled = true; this.UpdateLayout(); } } } } 

目前,我已经写了这篇文章并且它为我工作。

  Public Sub SendKey(ByVal key As Key) Dim args As New KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key) args.RoutedEvent = Keyboard.KeyDownEvent InputManager.Current.ProcessInput(args) End Sub Private Sub dataGrid_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles dataGrid.PreviewKeyDown Dim i As UIElement = e.OriginalSource Dim DG As DataGrid = sender If (e.Key = Key.Enter Or e.Key = Key.Return) AndAlso i IsNot Nothing Then MyBase.OnKeyDown(e) DG.CommitEdit() SendKey(Key.Tab) e.Handled = True End If End Sub