The WPF Datagrid has two selection modes, Single or Extended. The WPF ListView has a third - Multiple. This mode allows you to click and select multiple rows without CTRL or
I was creating an application with a similar requirement that would work for both touchscreen and desktop. After spending some time on it, the solution I came up with seems cleaner. In the designer, I added the following event setters to the datagrid:
Then in the codebehind, I handled the events as:
private void MouseEnterHandler(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed &&
e.OriginalSource is DataGridRow row)
{
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed &&
e.OriginalSource is FrameworkElement element &&
GetVisualParentOfType(element) is DataGridRow row)
{
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
private static DependencyObject GetVisualParentOfType(DependencyObject startObject)
{
DependencyObject parent = startObject;
while (IsNotNullAndNotOfType(parent))
{
parent = VisualTreeHelper.GetParent(parent);
}
return parent is T ? parent : throw new Exception($"Parent of type {typeof(T)} could not be found");
}
private static bool IsNotNullAndNotOfType(DependencyObject obj)
{
return obj != null && !(obj is T);
}
Hope it helps somebody else too.