WPF Datagrid Multiple Selection without CTRL or Space

Aran Mulholland picture Aran Mulholland · Jan 13, 2010 · Viewed 8.2k times · Source

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?

Answer

sumit picture sumit · Sep 18, 2012

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.