Я пробовал эти предложения и множество других, которые нашел на других сайтах, но ни один из них не помог мне. В итоге я создал следующее решение.
Я создал свой собственный элемент управления, унаследованный от DataGrid, и просто добавил к нему этот код:
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;
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;
}
}
Что все это делает?
Итак, каждый раз, когда мы щелкаем любую ячейку в нашей DataGrid, мы видим, содержит ли эта ячейка элемент управления CheckBox. Если это так , мы установим фокус на этот CheckBox и переключим его значение. .
Мне кажется, это работает, и это хорошее решение, которое легко использовать повторно.
Жаль, что нам нужно написать код. Объяснение того, что первый щелчок мышью (на CheckBox DataGrid) «игнорируется», поскольку WPF использует его для перевода строки в режим редактирования, может показаться логичным, но в реальном мире это идет вразрез с тем, как работает каждое реальное приложение.
Если пользователь видит на своем экране флажок, он должен иметь возможность щелкнуть по нему один раз, чтобы установить / снять флажок. Конец истории.