2012-05-01 32 views
12

Tôi muốn có một DataGrid Tuỳ chỉnh mà có thể,Di chuyển tiêu điểm đến ô tiếp theo trên phím Enter Nhấn trong WPF DataGrid?

  1. Di chuyển đến ô kế tiếp khi Nhập phím được nhấn cũng nếu nó đang trong chế độ chỉnh sửa.
  2. Khi cột cuối cùng trong hàng hiện tại đạt được, trọng tâm sẽ di chuyển đến ô đầu tiên của hàng tiếp theo.
  3. Khi đến ô tiếp theo, nếu ô có thể chỉnh sửa, ô đó sẽ tự động được chỉnh sửa.
  4. Nếu ô chứa ComboBox không phải comboboxcolumn, combobox sẽ DropDownOpen.

Hãy giúp tôi trong việc này. Tôi đã cố gắng từ vài ngày qua bằng cách tạo một DataGrid tùy chỉnh và đã viết một số mã trong

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

Nhưng tôi đã thất bại.

Trả lời

5
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<DataGridCellsPresenter>(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; 
} 
+0

Tôi đã làm điều gì đó tương tự trong một vài dự án, mã rất giống nhau. Tôi chỉ mở rộng datagrid và đóng gói một số lượng lớn những gì bạn đang làm trong đó. Vì vậy, tôi có thể xác nhận rằng điều này/câu trả lời của bạn chắc chắn hoạt động tuyệt vời! +1 –

+15

Thật tuyệt khi thấy mã bị thiếu: 'GetRow()', 'GetVisualChild ()' và 'dgIssuance' là gì? – bitbonk

+0

Tại sao bạn chuyển một giá trị mã cứng vào hàm GetCell của bạn ??? Câu hỏi là về việc di chuyển đến ** ô ** tiếp theo khi nhấn phím Enter, nhưng bạn đang cố gắng để có được một ô cuối cùng trong cột 2 của bạn trên Enter nhấp chuột. Tại sao? – AndreyS

2
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<DataGridCellsPresenter>(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(); 
      } 
     } 
    } 
} 

Đối với thời gian được, tôi viết bài này và làm việc của nó đối với tôi.

+0

Tôi gặp lỗi 'Lỗi Không tìm thấy loại' my: DataGridComboBoxColumn '. Xác minh rằng bạn không thiếu tham chiếu assembly và tất cả các assembly được tham chiếu đã được xây dựng. ' khi tôi mở rộng datagrid lớp wats sai – Mussammil

7

Triển khai đơn giản hơn nhiều. Ý tưởng là để nắm bắt sự kiện keydown và nếu phím là "Enter", sau đó di chuyển đến tab tiếp theo là ô tiếp theo của lưới.

/// <summary> 
/// On Enter Key, it tabs to into next cell. 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param> 
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)); 
    } 
} 
Các vấn đề liên quan