Я спробував ці пропозиції та багато інших, які я знайшов на інших сайтах, але жоден з них не працював для мене. Зрештою, я створив таке рішення.
Я створив свій власний 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;
// 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;
}
}
Що все це робить?
Щоразу, коли ми клацаємо на будь-якій комірці нашої DataGrid, ми бачимо, чи містить у ній елемент керування CheckBox. Якщо це так , то ми встановимо фокус на цей CheckBox і змінимо його значення .
Це, здається, працює для мене, і це приємне рішення, яке легко використовувати багаторазово.
Розчаровує, що для цього нам потрібно написати код. Пояснення того, що перший клік миші (на CheckBox DataGrid) "ігнорується", оскільки WPF використовує його для переведення рядка в режим редагування, може здатися логічним, але в реальному світі це суперечить тому, як працює кожна реальна програма.
Якщо користувач бачить прапорець на своєму екрані, він повинен мати можливість один раз натиснути на нього, щоб поставити галочку / зняти його. Кінець історії.