2011-01-05 10 views
1

Ich habe eine DataGrid mit wenigen bearbeitbaren Zellen. Benutzer können durch jede Zelle navigieren, um den Inhalt zu bearbeiten. Jetzt möchte ich die rechte Pfeiltaste wie Tab funktionieren. Wenn ein Benutzer die Bearbeitung einer Zelle beendet und die rechte Pfeiltaste drückt, bewegt sich der Fokus zur nächsten bearbeitbaren Zelle und beginnt mit der Bearbeitung.Wie man WPF Datagrid Pfeilschlüssel Navigation wie Tab Navigation implementieren

Zum Beispiel habe ich Folge Bildschirm:

Wenn der Benutzer drückt rechte Pfeiltaste, mag ich meinen Datagrid so sein:

Antwort

1

Das Datagrid eigentlich Auto - Griffe rechts, links, oben, nach unten weisende Pfeiltasten. Davon abgesehen können Sie den Zellfokus mit einem beliebigen dieser Schlüssel verschieben und dann mit dem Tippen beginnen, um in den Bearbeitungsmodus zu gelangen (falls die Zelle editierbar ist). Sie müssen keine Tasten drücken, um Ereignisse zu unterdrücken. Beachten Sie, dass Sie, wenn Sie "Enter" drücken, zur nächsten Zeile wechseln.

EDIT:

Natürlich durch die Pfeiltasten standardmäßig nicht eine Zelle in den Bearbeitungsmodus. Stattdessen müssen Sie Dinge eingeben oder den Mauszeiger verwenden. Aber Sie können Folgendes tun:

private void myDataGrid_CurrentCellChanged(object sender, EventArgs e) 
    { 
     myDataGrid.BeginEdit(); 
    } 

Dies wird die Zelle im Fokus in den Bearbeitungsmodus zu zwingen. Ich habe versucht, Key Event Handler zu verwenden, aber es scheint, dass das DataGrid den Benutzer nicht auf die Pfeiltasten und die Eingabe hören lässt (obwohl Sie könnten, wenn Sie WIN32 API verwenden). Wenn Sie jetzt eine der Pfeiltasten verwenden, befindet sich die neu ausgewählte Zelle im Bearbeitungsmodus. Versuche es mit Esc, um diesen Modus zu verlassen.

+0

für die Antwort Danke gesehen habe. Mein DataGrid funktioniert so, wie Sie es jetzt gesagt haben.Ich möchte jedoch, dass meine Datagrid-Zelle direkt in den Bearbeitungsmodus wechselt, wenn sie den Fokus erhält. Danke – Jing

+0

Ich habe gerade meine Antwort bearbeitet. HTH! – user1234567

+0

Vielen Dank für Ihre Antwort noch einmal. Jetzt geht meine Datagrid-Zelle direkt in den Bearbeitungsmodus. Aber wenn ich mit dem Bearbeiten einer Zelle fertig bin und die rechte Pfeiltaste drücke, bleibt sie immer noch in derselben Zelle, ohne zur nächsten editierbaren Zelle zu gehen. Kannst du mir eine Idee dazu geben? Danke – Jing

0

Dies ist der Code, den ich für die Navigation mit den Pfeiltasten

Sein in der Veranstaltung Datagrid_KeyUp platziert mit

DataGridCell DGcell = new DataGridCell(); 
    DGcell = GetCell(index, _Header); 
    if (DGcell != null) 
    { 
     CurrentCellContentType = DGcell.Content.GetType().Name.ToString(); 
    } 
    DataGridCell ProdCodeCell = GetCell(index, 0); 
    DataGridCell DescCell = GetCell(index, 1); 
    DataGridCell CostPriceCell = GetCell(index, 4); 
    DataGridCell VatRateCell = GetCell(index, 9); 

    DataGridCellInfo PCell = new DataGridCellInfo(ProdCodeCell); 
    DataGridCellInfo DCell = new DataGridCellInfo(DescCell); 
    DataGridCellInfo PriceCell = new DataGridCellInfo(CostPriceCell); 
    DataGridCellInfo VatCell = new DataGridCellInfo(VatRateCell); 

    string ProdCellContentType = PCell.Column.GetCellContent(PCell.Item).GetType().Name.ToString(); 
    string DescCellContentType = DCell.Column.GetCellContent(DCell.Item).GetType().Name.ToString(); 
    string PriceCellContentType = PriceCell.Column.GetCellContent(PriceCell.Item).GetType().Name.ToString(); 
    string VatCellContentType = VatCell.Column.GetCellContent(VatCell.Item).GetType().Name.ToString(); 

    switch (e.Key) 
    { 
    case Key.Left: 
     if (CurrentCellContentType == "TextBlock") e.Handled = false; 
     else if (CurrentCellContentType == "TextBox") 
     { 
      DataGridCellInfo cellLeft = new DataGridCellInfo(GetCell(index, _Header - 1)); 
      DgInvoiceLines.CurrentCell = cellLeft; 
     } 
     break; 
    case Key.Right: 
     if (CurrentCellContentType == "TextBlock") else e.Handled = false; 

     else if (CurrentCellContentType == "TextBox") 
     { 
      DataGridCellInfo cellRight = new DataGridCellInfo(GetCell(index, _Header + 1)); 
      DgInvoiceLines.CurrentCell = cellRight; 
     } 
     break; 
    case Key.Up: 
     if (index != 0) 
     { 
      if (CurrentCellContentType == "TextBlock") e.Handled = false; 
      else if (CurrentCellContentType == "TextBox") 
      { 
       DataGridCellInfo cellUp = new DataGridCellInfo(GetCell(index - 1, _Header)); 
       DgInvoiceLines.CurrentCell = cellUp; 
       DgInvoiceLines.SelectedItem = DgInvoiceLines.Items[index - 1]; 
      } 
     } 
     break; 

    case Key.Down: 
     if (CurrentCellContentType == "TextBlock") e.Handled = false; 
     else if (CurrentCellContentType == "TextBox") 
     { 
      DataGridCellInfo cellDown = new DataGridCellInfo(GetCell(index + 1, _Header)); 
      DgInvoiceLines.CurrentCell = cellDown; 
      DgInvoiceLines.SelectedItem = DgInvoiceLines.Items[index + 1]; 
     } 
     break; 

ich eine switch-Anweisung verwenden, um eine Nummer, die jeden Spaltenkopf

zuweisen HTH.

0

das ist meine Lösung, die funktioniert.

Im Konstruktor:

dataGridSubmissionData.KeyUp += DataGridSubmissionDataOnKeyUp; 
      dataGridSubmissionData.BeginningEdit += DataGridSubmissionDataOnBeginningEdit; 
      dataGridSubmissionData.CellEditEnding += DataGridSubmissionDataOnCellEditEnding; 
      dataGridSubmissionData.CurrentCellChanged += DataGridSubmissionDataOnCurrentCellChanged; 

In Körperklasse:

private bool isCellInEditionMode = false; 

private void DataGridSubmissionDataOnCurrentCellChanged(object sender, EventArgs eventArgs) 
     { 
      dataGridSubmissionData.BeginEdit(); 
     } 

     private void DataGridSubmissionDataOnCellEditEnding(object sender, DataGridCellEditEndingEventArgs dataGridCellEditEndingEventArgs) 
     { 
      isCellInEditionMode = false; 
     } 

     private void DataGridSubmissionDataOnBeginningEdit(object sender, DataGridBeginningEditEventArgs dataGridBeginningEditEventArgs) 
     { 
      isCellInEditionMode = true; 
     } 

private void DataGridSubmissionDataOnKeyUp(object sender, KeyEventArgs keyEventArgs) 
     { 
      if (keyEventArgs.Key == Key.Up || keyEventArgs.Key == Key.Down || keyEventArgs.Key == Key.Left || keyEventArgs.Key == Key.Right) 
      { 
       if (!isCellInEditionMode) 
        return; 

       dataGridSubmissionData.CommitEdit(); 

       var key = keyEventArgs.Key; // Key to send 
       var target = dataGridSubmissionData; // Target element 
       var routedEvent = Keyboard.KeyDownEvent; // Event to send 

       target.RaiseEvent(
        new KeyEventArgs(
         Keyboard.PrimaryDevice, 
         PresentationSource.FromVisual(target), 
         0, 
         key) {RoutedEvent = routedEvent} 
        ); 
      } 
     } 

Ich hoffe, dass meine Antwort jemand helfen.

0

Wenn Ihr Fall WPF gehostet Fenster ist, rief es Modeless WPF.

Und die Lösung könnte sein:

Window window = new Window(); 
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(window); 
window.Show(); 

ich die Lösung here