This project has moved. For the latest updates, please go here.
66
Vote

ListBoxDragDropTarget misses mouse up event occasionally

description

In the April 2010 release I've noticed that code that used to work fine in the March 2010 release is now behaving strangely. I have a ListBox that is wrapped in a ListBoxDragDropTarget element. When I click on an item in the list box to select it, sometimes a drag operation is started even though I did not hold down the mouse button. It seems to be fairly repeatable but not consistent. I can't detect a pattern.
 
Inside the ListBoxItem is an object which is listening to mouse events for detecting double click so I will investigate that and report back but I just wanted to post this in case anyone else is noticing the same thing.

file attachments

comments

einsteintech wrote Apr 16, 2010 at 5:45 PM

I have verified that this also happens in the Toolkit Samples so I don't think it has anything to do with my customized ItemTemplate. It seems to happen mostly when you click and then release while moving the mouse. I have managed to come up with a workaround that seems to fix the issue for me. I subclassed ListBoxDragDropTarget and add my own mouse monitoring event handlers and block the call to base.OnItemDragStarting (since setting e.Cancel has no effect). The code is attached.

wrote Apr 16, 2010 at 5:45 PM

wrote Apr 30, 2010 at 7:57 AM

salmonpv wrote Apr 30, 2010 at 8:10 AM

I have a similar problem... But I just started using the Drag and Dropping. I thought it was the standard behavior for the ListBoxDragDropTarget to start dragging as soon as the mouse button is pressed. So I started my own implementation with a content control. What I found is that the LeftMouseButtonUp only fires occasionally. Well in my instance, the content in the list box item change if the item is selected. As soon as I click on list box item, and the item change (because its selected) and my mouse pointer is over a hyper link button (could be any control haven't checked) after I clicked the mouse up does not fire. ect. Dragging can not be canceled. I'm only assuming that they implemented it checking if a mouse up event has fired to Drop or cancel the drop.

The your solution helped me. The handledEventsToo parameter in the AddHandle method seems to do the trick. My guess is that somewhere in the new release some one is handling the mouse up event.

wrote May 11, 2010 at 9:39 AM

CominottoGert wrote May 16, 2010 at 4:38 PM

This workaround doesn't really fix everything for me, but I hope it does for others. Anyway, this should be fixed asap..

TKelley wrote May 21, 2010 at 2:32 AM

I'm noticing the same thing. In my case after I select an item in the list box suddenly I'm in a drag operation without having the mouse button down. I tried the work around but it seem to cause problems getting a drag operation to start.

wrote May 21, 2010 at 2:32 AM

wrote May 21, 2010 at 8:57 AM

wrote Jun 1, 2010 at 11:32 AM

wrote Jun 4, 2010 at 7:39 PM

wrote Jun 4, 2010 at 7:46 PM

tearaway_Tea wrote Jun 4, 2010 at 7:47 PM

I have got the similar issue. There is a thread about that on silverlight forums: http://forums.silverlight.net/forums/p/180216/423389.aspx. Basically I have started to look into the Toolkit's code, and found out that the problem is in DragDropTarget class's method: IObservable<IEvent<ItemDragEventArgs>> GetItemDragStarting().

There is a bunch of RX-style code which defines the workflow: If mouse down, start to listen mouse move, if mouse is out of the 4x4 offset then raise the start drag event until mouse up.

But it looks like that the workflow is broken sometimes and start drag event is raised even after mouse up has been performed. I guess that is somehow relates to unstable set of RX event wrappers and extension method.

I'm trying to fix the issue by myself, but the lack of RX-style development experience doesn't give me the easy chance to resolve this quick. Maybe someone can provide the patch or guideline how to resolve it until the next release of Toolkit.

I'm attaching a screen-cast with the example how the issue looks like in runtime.

wrote Jun 4, 2010 at 8:27 PM

wrote Jun 5, 2010 at 1:41 AM

wrote Jun 6, 2010 at 5:10 PM

wrote Jun 7, 2010 at 7:41 AM

wrote Jun 23, 2010 at 8:29 AM

wrote Jun 28, 2010 at 7:04 AM

nayato wrote Jun 28, 2010 at 7:36 AM

Given fix helps a bit but still while using stylus I can reproduce the situation quite easily.

wrote Jun 29, 2010 at 5:50 PM

wrote Jun 29, 2010 at 6:17 PM

wrote Jul 13, 2010 at 3:58 PM

wrote Jul 14, 2010 at 7:48 AM

wrote Jul 14, 2010 at 7:59 AM

wrote Jul 15, 2010 at 4:28 PM

wrote Jul 25, 2010 at 12:01 PM

druzil wrote Jul 25, 2010 at 12:07 PM

This is happening on the TreeViewDragDropTarget as well. I handle the mouseleftbuttonup event also, which means I'm getting both functionality firing at the same time. setting e.Handled = true in the buttonup doesn't appear to make any difference.

druzil wrote Jul 26, 2010 at 2:57 PM

further investigation seems to show that it only occurs for the first click and then drag completion. The problem then disappears which may be why you are finding it is inconsistent. If you don't complete the drag operation that is initiated by the first click then the problem will occur on the subsequence click.

druzil wrote Jul 26, 2010 at 5:05 PM

Commenting out the .Take(1) in the GetItemDragStarting appears to make the problem go away. I'm not sure what the side affect of this is - obviously it was there for a reason (could be that this is fine for just the TreeViewDragDropTarget class), Haven't figured out how to debug/breakpoint with the reactive code to test the event being skipped in the GetMouseMove method.

druzil wrote Jul 29, 2010 at 4:16 PM

Ignore that last comment it appeared to work on the day but doesn't make any difference now

wrote Jul 30, 2010 at 10:43 AM

wrote Jul 30, 2010 at 4:21 PM

wrote Aug 30, 2010 at 2:25 PM

wrote Sep 8, 2010 at 10:42 AM

johnnyjob wrote Sep 14, 2010 at 8:36 PM

I definitely can reproduce the bug with a ListBox. The updated version of ListBoxDragDropTarget (from FixedListBoxDragDropTarget.txt) doesn't make any difference.
Users notice this issue very easily, so I wonder why the bug is classified as low priority. It breaks your whole feature, guys!

wrote Sep 14, 2010 at 8:36 PM

wrote Sep 24, 2010 at 9:08 AM

wrote Oct 1, 2010 at 1:20 PM

wrote Oct 13, 2010 at 5:47 PM

wrote Oct 28, 2010 at 4:35 AM

PeteTheGeek wrote Nov 30, 2010 at 2:33 PM

The DataGridDragDropTarget unfortunately seems to have the same bug. Using subclassing as per the sample code seems to work but have not done extensive testing yet.

wrote Nov 30, 2010 at 2:33 PM

wrote Dec 16, 2010 at 5:53 PM

wrote Dec 29, 2010 at 10:18 AM

wrote Jan 11, 2011 at 12:56 AM

wrote Jan 13, 2011 at 8:33 PM

wrote Jan 18, 2011 at 12:52 AM

wrote Jan 19, 2011 at 8:02 AM

JohnnyLuo wrote Jan 27, 2011 at 2:48 AM

The fix post in this thread works fine. but hope toolkit can fix it.

wrote Jan 27, 2011 at 3:18 AM

wrote Jan 31, 2011 at 10:55 PM

wrote Feb 17, 2011 at 3:29 PM

wrote Feb 19, 2011 at 7:44 PM

troelsrichter wrote Feb 19, 2011 at 7:55 PM

I'm having the same problem, but the fix doesn't do it for me. No change in behavior :(

wrote Feb 23, 2011 at 8:41 AM

hugoxp wrote Mar 4, 2011 at 2:13 PM

Same issue... is there any other solution beside "FixedListBoxDragDropTarget.txt"?
thnak you

wrote Mar 6, 2011 at 11:44 PM

wrote Mar 7, 2011 at 12:00 AM

wrote Mar 7, 2011 at 2:09 AM

xps wrote Mar 7, 2011 at 2:09 AM

I also have the same issue with a TreeViewDragDropTarget (as well as a DataGridDragDropTarget).

I have tried the FixedListBoxDragDropTarget but without luck.

I can reproduce the bug close to 100% of the time by:
  • Moving the mouse quickly around the TreeView
  • Quickly clicking (mouse down & up) while the mouse is still moving and is over one of the items
    I will then end up with a drag operation started and the mouse button released already.
I have logged the events and found that in this particular scenario they happen in this order:
  1. MouseLeftButtonDown
  2. OnItemDragStarting
  3. MouseLeftButtonUp
Which is why the FixedListBoxDragDropTarget doesn't work - it assumes that the MouseLeftButtonUp event would occur before the OnItemDragStarting (since OnItemDragStarting then gets ignored).

I came up with another fix by delaying the OnItemDragStarting event, so that the MouseLeftButtonUp gets a chance to occur before OnItemDragStarting.
It is not perfect though:
  • It will introduce a delay between the time of the click and the time the drag operation actually starts
  • There is a risk that the internal drag initiation logic (which seems to have something to do with thumbnail generation) still takes longer than the introduced delay in which case the bug will still occur.
I have set the delay to 300ms through trial and error. This can be adjusting higher (to make sure the bug will never happen) or lower (to reduce the delay).
I have attached the code (DelayFix.txt), hopefully it can be useful to someone. Any feedback is welcome.

wrote Mar 8, 2011 at 9:56 PM

wrote Mar 13, 2011 at 9:46 PM

wrote Mar 31, 2011 at 6:37 PM

breed052 wrote Mar 31, 2011 at 6:37 PM

My treeview has an expanderbutton which is a togglebutton, and on first loading the Treeview items, if I click the togglebutton and then move the mouse at all, the drag is initiated, even if AllowDrop was bound to a value that was false at the time.

wrote Apr 3, 2011 at 7:55 AM

wrote May 16, 2011 at 2:53 PM

wrote May 17, 2011 at 5:34 PM

wrote Jun 17, 2011 at 11:20 AM

wrote Jun 29, 2011 at 3:12 AM

wrote Jul 6, 2011 at 7:31 PM

rbandala wrote Jul 6, 2011 at 7:32 PM

delay fix works up to certain extent.

wrote Jul 18, 2011 at 10:56 AM

wrote Aug 2, 2011 at 4:35 PM

felix7 wrote Aug 4, 2011 at 8:38 PM

I am having the same issue, and the fix provided does not work. When is this issue going to get fixed?

wrote Aug 5, 2011 at 5:53 PM

chrishallowell wrote Aug 5, 2011 at 6:06 PM

Having the same problem. I tried the fix: DelayFix.txt but that doesn't fix the problem.
As someone else has already stated: This issue only occurs for the first click and then drag completion. The problem then disappears. Is there a way to simulate this first click/drag in code so the user doesn't encounter this?

hugoxp wrote Aug 6, 2011 at 9:44 AM

Hi,

After some research I've found this GREAT class made by KevD:
http://silverlightdragdrop.codeplex.com/

It's great and bug free.

Daringleo wrote Aug 8, 2011 at 9:53 PM

Is there any updates on this issue? I am still facing it in DatagridDragDropTarget!

wrote Aug 12, 2011 at 8:14 PM

wrote Aug 14, 2011 at 9:42 AM

safor wrote Aug 14, 2011 at 10:14 AM

I adapted code from FixedListBoxDragDropTarget.txt for the DataGridDragDropTarget class and it fixed the issue with unpredictable starting of drag and drop. Looking forward for the official fix.

wrote Aug 19, 2011 at 8:35 PM

wrote Sep 16, 2011 at 10:50 AM

pozi wrote Sep 16, 2011 at 10:54 AM

thanks a lot for the fix, einsteintech

wrote Sep 22, 2011 at 3:24 AM

andy2001p wrote Oct 7, 2011 at 6:15 AM

This does not fix my problem, but it does help me come up a good solution.
Instead of overriding OnItemDragStarting method, I am overriding another one, which essentially solved the problem.
    protected override void OnQueryContinueDrag(QueryContinueDragEventArgs args)
    {
        if (!IsMouseDown)
        {
            args.Action = DragAction.Cancel;
            args.Handled = true;
        }
        base.OnQueryContinueDrag(args);
    }

wrote Dec 20, 2011 at 11:41 AM

wrote Jan 2, 2012 at 12:18 PM

wrote May 16, 2012 at 1:30 PM

wrote May 22, 2012 at 1:42 PM

wrote Jun 5, 2012 at 8:48 PM

wrote Jul 11, 2012 at 8:13 PM

wrote Jul 14, 2012 at 4:35 AM

jandersen78 wrote Jul 14, 2012 at 5:55 AM

I think I get where andy2001p was going with his change... essentially use the OnQueryContinueDrag hook to cancel the drag operation if you find that the mouse left button is up. However, I found that this prevented ANY drag operation from succeeding because, in a normal drag, OnQueryContinueDrag is called BEFORE the drop handlers so it appears my drops were being cancelled just before they should've succeeded. I simply changed his code block to set DragAction.Drop instead of DragAction.Cancel and that SEEMS to be working well for my needs (I'm working with a custom DragDropTarget). The effect is simply to immediately trigger a drop if you find that the mouse is no longer down.

wrote Feb 22, 2013 at 1:52 AM

wrote Apr 25, 2013 at 2:24 PM

bigfootsoft wrote Apr 25, 2013 at 2:24 PM

I don't know if anyone is still reading this post, but I'm still gonna post my solution here. I'm currently developing an application where this problem was annoying me a lot. I tried subclassing the DDT using the suggestions posted above but they did not really help.

So I did some research and found out that the "normal" sequence of the drag/drop/mouse-events would be:
1. MouseLeftButtonDown
2. OnItemDragStarting
3. OnQueryContinueDrag (multiple times)
4. MouseLeftButtonUp
5. OnQueryContinueDrag
In those cases where the item would stick to my cursor, the sequence was slightly different:
1. MouseLeftButtonDown
2. OnItemDragStarting
3. MouseLeftButtonUp
4. OnQueryContinueDrag (to infinity and beyond)
Notice the missing OnQueryContinueDrag between MouseDown and MouseUp. So you can solve the problem using two flags:
HasQueriedContinueDrag: set to false in MouseDown, set to true in QueryContinueDrag
and
CancelDrag: set to false in MouseDown, set to true in MouseUp if HasQueriedContinueDrag is false

If CancelDrag is set then cancel the dragging operation in OnQueryContinueDrag like andy2001p suggested.

I've attached my complete solution. It is in VB.net but should be pretty self-explanatory, even for C#-ers ;)

wrote Jan 10, 2014 at 6:45 AM

bharatleel wrote Jan 20, 2014 at 1:21 PM

I am also facing the same Mouse capture release issue even I have also raise same issue and also found another post regarding this issue.

andy2001p has suggested very nice solution but not fixing the issue, So now my application is running smoothly but some time shadow is sticks with mouse cursor not item.

Is there any solution about that shadow copy while dragging element?
If yes then please help me out...

Thanks

bhalgatashish wrote Mar 19, 2014 at 2:18 PM

Thanks the code in FixedListBoxDragDropTarget v2.txt worked.
I think it worked 95% of the time. Thanks man.

70sCommander wrote May 26, 2014 at 8:00 AM

Hello Community,

the workaround provided by bigfootsoft fixed our problem without using timers! (which are always no solution to the problem!)
Here is the code:
using System.Windows.Input;
using Microsoft.Windows;

namespace XYZ.Controls.TreeView
{
    using Nodes;
    using XYZ.Nodes;
    using XYZ.Nodes.StaticNodes.AnchorNodes;
    using System.Windows.Controls;

    public class XYZTreeViewDragDropTarget : TreeViewDragDropTarget
    {
        private bool leftButtonUp = false;
        private bool hasQueriedContinueDrag;
        private bool cancelDrag;

        public XYZTreeViewDragDropTarget()
        {
            AddHandler(MouseLeftButtonUpEvent, new MouseButtonEventHandler(HandleMouseLeftButtonUp), true);
            AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(HandleMouseLeftButtonDown), true);
        }

        private void HandleMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            hasQueriedContinueDrag = false;
            cancelDrag = false;

            base.OnMouseLeftButtonDown(e);
        }

        private void HandleMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
             if (!hasQueriedContinueDrag)
                 cancelDrag = true;

             base.OnMouseLeftButtonUp(e);
        }

        protected override void OnQueryContinueDrag(QueryContinueDragEventArgs args)
        {
            hasQueriedContinueDrag = true;

            if (cancelDrag)
            {
                args.Action = DragAction.Cancel;
                args.Handled = true;
            }
            base.OnQueryContinueDrag(args);
        }
    }
}