2013-06-14 8 views
6

Ho un DataGrid in cui il SelectedItem è associato a una proprietà VM selezionata. Ho un controllo di ricerca che farà una ricerca e il SelectedItem delle modifiche DataGrid (e scorre in vista). WPF 4.0 e DataGridSelectionUnit="FullRow".Focus su DataGridCell per SelectedItem quando DataGrid riceve il focus sulla tastiera

Il mio problema riguarda lo stato attivo. Il DataGrid viene attivato (tramite allegato proprietà/binding), ma non è possibile utilizzare il Up, Giù, Page Up, Page Down tasti per cambiare le righe (SelectedItem). Se faccio di nuovo da tab, viene selezionata la prima cella della prima riga che cambia lo SelectedItem.

In conclusione, come è possibile assegnare lo stato attivo della tastiera a DataGridCell per SelectedItem quando lo stato di attivazione è DataGrid?

Ci sono così tante domande DataGrid/Focus e già provato alcune cose. Grazie per l'aiuto.

risposta

7

È necessario fornire la messa a fuoco logica della riga selezionata. Dopo aver selezionato il nuovo elemento provare a sostituire il vostro SetFocus chiamata con questo:

 var selectedRow = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(dataGrid1.SelectedIndex); 
     FocusManager.SetIsFocusScope(selectedRow, true); 
     FocusManager.SetFocusedElement(selectedRow, selectedRow); 
+0

funzionato perfettamente! Metti questo nel gestore di eventi GotKeyboardFocus e chiameresti solo se e.NewFocus è DataGrid. – KornMuffin

+0

@KornMuffin lo stai usando in WPF il mio non funziona voglio solo concentrarmi sul mio datagrid che i tasti freccia funzionano ma non funziona nessuna soluzione per favore – Ahmad

+0

@Ahmad Sì, WPF. My DataGrid.SelectionUnit è FullRow. Non sono sicuro se questo farà la differenza per te o no. – KornMuffin

0

Questo PowerShell Snippet ha lavorato per me:

$dataGrid = ...  
$dataGrid.add_GotKeyboardFocus({ 
    param($Sender,$EventArgs) 
    if ($EventArgs.OldFocus -isnot [System.Windows.Controls.DataGridCell) { 
     $row = $dataGrid.ItemContainerGenerator.ContainerFromIndex($dataGrid.SelectedIndex) 
     $row.MoveFocus((New-Object System.Windows.Input.TraversalRequest("Next"))) 
    } 
}) 
0

La soluzione FocusManager non ha funzionato per me per qualche motivo. Inoltre ho richiesto un apporach più generale. Così qui è, ciò che mi si avvicinò con:

using System.Windows.Controls; 

public static void RestoreFocus(this DataGrid dataGrid, 
            int column = 0, bool scrollIntoView = false) 
{ 
    if (dataGrid.IsKeyboardFocusWithin && dataGrid.SelectedItem != null) 
    { 
     // make sure everything is up to date 
     dataGrid.UpdateLayout(); 

     if (scrollIntoView) 
     { 
      dataGrid.ScrollIntoView(dataGrid.SelectedItem); 
     } 

     var cellcontent = dataGrid.Columns[column].GetCellContent(dataGrid.SelectedItem); 
     var cell = cellcontent?.Parent as DataGridCell; 
     if (cell != null) 
     { 
      cell.Focus(); 
     } 
    } 
} 

e chiamarlo in questo modo:

MyDataGrid.IsKeyboardFocusWithinChanged += (sender, e) => 
{ 
    if ((bool)e.NewValue == true) 
    { 
     Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() => 
     { 
      MyDataGrid.RestoreFocus(scrollIntoView: true); 
     })); 
    } 
};