WPF Drag & drop from ListBox with SelectionMode Multiple

前端 未结 4 1292
后悔当初
后悔当初 2020-12-29 22:47

I\'ve almost got this working apart from one little annoying thing...

Because the ListBox selection happens on mouse down, if you start the drag with the mouse down

4条回答
  •  借酒劲吻你
    2020-12-29 23:11

    I've found a very simple way to enable Windows Explorer like drag/drop behaviour when having multiple items selected. The solution replaces the common ListBox with a little derived shim that replaces the ListBoxItem with a more intelligent version. This way, we can encapsulate the click state at the right level and call into the protected selection machinery of the ListBox. Here is the relevant class. For a complete example, see my repo on github.

    public class ListBoxEx : ListBox
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new ListBoxItemEx();
        }
    
        class ListBoxItemEx : ListBoxItem
        {
            private bool _deferSelection = false;
    
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                if (e.ClickCount == 1 && IsSelected)
                {
                    // the user may start a drag by clicking into selected items
                    // delay destroying the selection to the Up event
                    _deferSelection = true;
                }
                else
                {
                    base.OnMouseLeftButtonDown(e);
                }
            }
    
            protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
            {
                if (_deferSelection)
                {
                    try
                    {
                        base.OnMouseLeftButtonDown(e);
                    }
                    finally
                    {
                        _deferSelection = false;
                    }
                }
                base.OnMouseLeftButtonUp(e);
            }
    
            protected override void OnMouseLeave(MouseEventArgs e)
            {
                // abort deferred Down
                _deferSelection = false;
                base.OnMouseLeave(e);
            }
        }
    }
    

提交回复
热议问题