Wednesday, March 9, 2011

Dragging Multiselected Rows in WPF GridView

When setting the GridView’s selection mode to Extended, you gain the ability to select multiple rows using either the Shift and Ctrl keys.

If you then intended on being able to drag those rows off of the gridview to another control that accepts a drop operation, an end user is familiar with left-clicking on any of the selected rows and dragging the mouse while still holding the left button down.  Unfortunately in WPF, as soon as the MouseDownEvent completes, the other selected rows become unselected and the only one that remains is the one under the mouse.

The good news is that you can achieve that expected experience by overriding only a couple mouse events on your listviewitems.

First, you will need to override the ListView so you can add your own special ListViewItems to it.

public class MyListView : ListView
{
protected override DependencyObject GetContainerForItemOverride()
{
return new MyListItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is MyListItem;
}
}

And now you can create your new custom class that does the work.  The sample below overrides the OnMouseLeftButtonDown event.  I have also made this work similarly using the OnPreviewMouseLeftButtonDown by setting the e.Handled = true; (instead of just calling return) and while using the same test conditions.  So if you have existing overrides to do other code-behind on your listview already, you should be able to pick and choose which function jives best in your situation.
public class MyListItem : ListViewItem
{
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (IsSelected && ((Keyboard.Modifiers & ModifierKeys.Control) == 0))
return;

base.OnMouseLeftButtonDown(e);
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
if ((Keyboard.Modifiers & ModifierKeys.Control) == 0)
base.OnMouseLeftButtonDown(e);

base.OnMouseLeftButtonUp(e);
}
}

All of the code samples I found while searching for this solution would only work partially.  Most samples missed the ability to handle the [ctrl] click situations that should allow me to change selection on individual rows while not affecting the others.  This sample should handle all the extended click scenarios.

No comments:

Post a Comment