Ho provato questi suggerimenti e molti altri ho trovato su altri siti, ma nessuno di questi ha funzionato abbastanza per me. Alla fine, ho creato la seguente soluzione.
Ho creato il mio controllo ereditato da DataGrid e ho semplicemente aggiunto questo codice:
public class DataGridWithNavigation : Microsoft.Windows.Controls.DataGrid
{
public DataGridWithNavigation()
{
EventManager.RegisterClassHandler(typeof(DataGridCell),
DataGridCell.PreviewMouseLeftButtonDownEvent,
new RoutedEventHandler(this.OnPreviewMouseLeftButtonDown));
}
private void OnPreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
{
DependencyObject obj = FindFirstControlInChildren(cell, "CheckBox");
if (obj != null)
{
System.Windows.Controls.CheckBox cb = (System.Windows.Controls.CheckBox)obj;
cb.Focus();
cb.IsChecked = !cb.IsChecked;
}
}
}
public DependencyObject FindFirstControlInChildren(DependencyObject obj, string controlType)
{
if (obj == null)
return null;
// Get a list of all occurrences of a particular type of control (eg "CheckBox")
IEnumerable<DependencyObject> ctrls = FindInVisualTreeDown(obj, controlType);
if (ctrls.Count() == 0)
return null;
return ctrls.First();
}
public IEnumerable<DependencyObject> FindInVisualTreeDown(DependencyObject obj, string type)
{
if (obj != null)
{
if (obj.GetType().ToString().EndsWith(type))
{
yield return obj;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
foreach (var child in FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type))
{
if (child != null)
{
yield return child;
}
}
}
}
yield break;
}
}
Cosa fa tutto questo?
Bene, ogni volta che facciamo clic su qualsiasi cella nel nostro DataGrid, vediamo se la cella contiene un controllo CheckBox al suo interno. Se lo fa , allora ci concentreremo su quel CheckBox e commuteremo il suo valore .
Questo sembra funzionare per me ed è una soluzione piacevole e facilmente riutilizzabile.
E 'deludente che abbiamo bisogno per scrivere il codice per fare questo però. La spiegazione che il primo clic del mouse (su CheckBox di un DataGrid) viene "ignorata" quando WPF lo usa per mettere la riga in modalità Modifica potrebbe sembrare logica, ma nel mondo reale, questo va contro il modo in cui funziona ogni vera applicazione.
Se un utente vede una casella sullo schermo, dovrebbe essere in grado di fare clic su di essa una volta per spuntarla / deselezionarla. Fine della storia.