Wypróbowałem te sugestie i wiele innych, które znalazłem na innych stronach, ale żadna z nich nie działała dla mnie. W końcu stworzyłem następujące rozwiązanie.
Utworzyłem własną kontrolkę odziedziczoną po DataGrid i po prostu dodałem do niej następujący kod:
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;
}
}
Co to wszystko robi?
Cóż, za każdym razem, gdy klikamy dowolną komórkę w naszym DataGrid, sprawdzamy, czy komórka zawiera w sobie kontrolkę CheckBox. Jeśli to robi , wtedy będziemy ustawić ostrość na tym CheckBox i przełączania jego wartość .
Wydaje mi się, że to działa i jest przyjemnym rozwiązaniem, które można łatwo wykorzystać ponownie.
To rozczarowujące, że my potrzebujemy do zapisu kodu to zrobić chociaż. Wyjaśnienie, że pierwsze kliknięcie myszą (na polu CheckBox DataGrid) jest „ignorowane”, ponieważ WPF używa go do przestawienia wiersza w tryb edycji, może wydawać się logiczne, ale w rzeczywistości jest to sprzeczne ze sposobem działania każdej prawdziwej aplikacji.
Jeśli użytkownik widzi pole wyboru na swoim ekranie, powinien móc je raz kliknąć, aby zaznaczyć / odznaczyć. Koniec opowieści.