Reputation: 56727
I want to implement drag & drop for a extended-selection-mode WPF ListBox
. So far, everything is working fine:
I basically implemented it as written here - in short:
PreviewMouseLeftButtonDown
to store current mouse positionMouseMove
to initiate the drag operation if distance has been coveredNow my problem is: Usually, in the Explorer for example, I'd select the items I want to drag, then I release the mouse button and press it again to initiate the drag & drop operation. I guess that's how most users would do it. When I do the same thing in my application now, the selection changes to the item I press the mouse button on for the second time - the multi-selection is gone.
I googled a lot yesterday, but all the solutions I could find initiated the drag operation in PreviewMouseLeftButtonDown
. That, however, does not allow me to check whether the mouse has been moved far enough to actually initiate a drag operation.
My question: Does anyone have a simple solution (not involving any third-party libraries) how I can change the sample linked above so that the multi-selection stays intact?
Upvotes: 3
Views: 1505
Reputation: 8786
The problem is that the selection-mode of ListBox
or ListView
are different with the one used for Explorer:
For ListBox
with extended-selection-mode:
User can de-select item with just MouseDown;
while for Explorer:
User can not de-select item with just MouseDown, they can only do it until MouseUp.
So that's core reason behind why in Explorer, user can select an item, release Mouse, and then press it again to start the drag & drop.
In order to implement Explorer-like selection and drag&drop effect, you need to first differentiate if an item is selected when MouseDown, so when an item IsSelected
you will defer it's selection change until MouseUp.
You can check this article for more ideas and here is a prototype for you to start with:
private void ListBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (VisualTreeHelper.GetParent(e.OriginalSource as UIElement) is ListBoxItem)
{
ListBoxItem item = (ListBoxItem)VisualTreeHelper.GetParent(e.OriginalSource as UIElement);
if (item == null) return;
if (item.IsSelected)
{
e.Handled = true;
}
}
}
Upvotes: 3