Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF drag and drop from a ListBox that has SelectionMode=Extended

I have a ListBox and want the selection-mode to be extended. Also I want have to implement drag and drop functionality. The problem now is, that if the mouse is clicked on a selected item, it will be immediately be selected as single selection instead of waiting to the mouse-up-event for doing this.

Due to this behaviour, start dragging multiple items is for the user quasi impossible because always he clicks on the selection to start dragging, the selection changes to the item that is under the mouse and starts the drag-operation with this item.

Is there a good workaround for this problem or does even exists an official solution?

like image 716
HCL Avatar asked Sep 22 '10 08:09

HCL


2 Answers

Here's what I've done. In your DragDrop code, subscribe to the PreviewMouseLeftButtonDown. If the item you are already clicking on is selected, then set e.Handled to true.

In my sample below, I identify a part of the list box item as a drag grip (with bumps) so that I can distinguish between the item and a drag surface. I just had to get the list box item data template and the drag and drop behavior to agree on a name of the drag grip element.

The PreviewMouseLeftButtonDown from my work in progress:

private void ItemsControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    dragStartPoint = e.GetPosition(null);

    ItemsControl itemsControl = this.AssociatedObject as ItemsControl;
    if (itemsControl != null)
    {
        this.sourceItemContainer = itemsControl.ContainerFromElement((Visual)e.OriginalSource) as FrameworkElement;
    }

    // If this is an multiple or extended selection list box, and on a drag grip, then ensure the item being hit is selected
    // This prevents the ItemsControl from using this MouseDown to change selection, except over a selected item's drag grip.            
    if ((this.IsMultipleSelectionListBox() == true) && (this.IsOriginalSourceDragGrip(e) != false) && (this.IsSourceListBoxItemSelected() == true))
    {
        e.Handled = true;
    }
}
like image 67
Geoff Cox Avatar answered Nov 20 '22 15:11

Geoff Cox


The easiest workaround i can think of would be to change the ListBoxItem to select on MouseUp not Down like so and change the ContainerGenerator to serve your custom ListBoxItems:

public class CustomListBoxItem : ListBoxItem  
{  
    protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e )  
    {  
        //do nothing
    }  

    protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e )  
    {  
        base.OnMouseLeftButtonDown( e );  
    }  
}  

You might need some MouseLeave/LeftButtonDown logic if you want to prevent different items selecting when moving through the List while holding the mouse button down.

like image 34
MrDosu Avatar answered Nov 20 '22 16:11

MrDosu