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 Shift being held down. Anyone know how to do this for the datagrid?
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:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<EventSetter Event="MouseEnter" Handler="MouseEnterHandler"></EventSetter>
<EventSetter Event="PreviewMouseDown" Handler="PreviewMouseDownHandler"></EventSetter>
</Style>
</DataGrid.RowStyle>
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<DataGridRow>(element) is DataGridRow row)
{
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
private static DependencyObject GetVisualParentOfType<T>(DependencyObject startObject)
{
DependencyObject parent = startObject;
while (IsNotNullAndNotOfType<T>(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<T>(DependencyObject obj)
{
return obj != null && !(obj is T);
}
Hope it helps somebody else too.