Gong-wpf-dragdrop: ListBox drag and drop - touch screen

Created on 1 Oct 2014  ·  19Comments  ·  Source: punker76/gong-wpf-dragdrop

I cant use drag and drop functionality on touch screens with ListBox/ListView.

Is it planned in the future or has anyone a workaround for it?

Feature Request

Most helpful comment

Adding ScrollViewer.PanningMode="None" to ListBox fixed it. I spent half the day working on this and you just saved me the other half! Thanks you so much!!!

All 19 comments

@psoma i would do this, but i can't test this in the real world, cause i don't have any touchable device :-(

There's also the question of how one wants to begin the drag operation,
some things make sense to begin a drag on touch down, others probably want
a long press.
On Oct 1, 2014 11:28 AM, "Jan Karger" [email protected] wrote:

@psoma https://github.com/psoma i would do this, but i can't test this
in the real world, cause i don't have any touchable device :-(


Reply to this email directly or view it on GitHub
https://github.com/punker76/gong-wpf-dragdrop/issues/110#issuecomment-57512449
.

What kind of touch screen are you using ? I'm using this library with a resistive touch-screen and i don't have any issues.

It's created by using DoDragDrop().

The touchscreen was on our test machine, I think a Lenovo Yoga 2 tablet.

Having same issue on all touch screens. Testing with Surface Pro 2, 3, and 4.

I had a similar issue and in the end settled on it being a conflict between the native inertial scrolling in listbox and derived controls. It makes sense in that it's quite hard to tell the difference between a "press and move, meaning scroll the window" and a "press and move. meaning pick up that item for a drag"

You could try disabling PanningMode, that may help?

Adding ScrollViewer.PanningMode="None" to ListBox fixed it. I spent half the day working on this and you just saved me the other half! Thanks you so much!!!

No problem, glad it helped you out :D

Problem is, setting the PanningMode is barely a work-around, and having a touch enabled application where you can't scroll a list with touch is a no go. Any udpate on this ? @punker76
Something based on a hold gesture to trigger the drag would be great, but I have yet to figure out how to implement it

I don't know if this helps, or if there are obvious holes in this I haven't realized yet, but a work-around that _seems_ to be working for me is:

  • Leave PanningMode set to its default value (Both, I believe?)
  • In the SelectionChanged event, change PanningMode to None
  • Set a timer that fires after some brief interval (800 milliseconds seems reasonable for my particular application)
  • When the timer fires, turn the timer back off, and reset PanningMode to Both

Pseudo-y code:

  ctor()
  {
    // There are of course a bunch of different timers. When coding this, I got my
    // grubby fingers onto System.Timers.Timer first, so that's what I used here :-P
    _touchDragTimer = new Timer();
    _touchDragTimer.Interval = 800;
    _touchDragTimer.Elapsed += _touchDragTimer_Elapsed;
  }

  void lstItems_SelectionChanged(sender, e)
  {
    _touchDragTimer.Stop();
    lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.None);
    _touchDragTimer.Start();
  }

  void _touchDragTimer_Elapsed(sender, e)
  {
    _touchDragTimer.Stop();

    Dispatcher.Invoke(
      () =>
      {
        lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both);
      });
  }

With this code, you can drag the view around as much as you want, but if you want to drag an item, tap it once to select it, and then you have a brief interval within which to start a drag operation. Let it sit, and it reverts to scrolly behaviour.

I haven't investigated whether this would be easy to integrate directly into GongSolutions.Wpf.DragDrop, but maybe someone might find it useful (or be able to tell me why I shouldn't be doing it! :-D).

Tap-release-hold-drag is a fairly common gesture to indicate that you want to do a drag rather than a scroll.

I'm also interested in this feature, would be great to have it!

I don't know if this helps, or if there are obvious holes in this I haven't realized yet, but a work-around that _seems_ to be working for me is:

  • Leave PanningMode set to its default value (Both, I believe?)
  • In the SelectionChanged event, change PanningMode to None
  • Set a timer that fires after some brief interval (800 milliseconds seems reasonable for my particular application)
  • When the timer fires, turn the timer back off, and reset PanningMode to Both

Pseudo-y code:

  ctor()
  {
    // There are of course a bunch of different timers. When coding this, I got my
    // grubby fingers onto System.Timers.Timer first, so that's what I used here :-P
    _touchDragTimer = new Timer();
    _touchDragTimer.Interval = 800;
    _touchDragTimer.Elapsed += _touchDragTimer_Elapsed;
  }

  void lstItems_SelectionChanged(sender, e)
  {
    _touchDragTimer.Stop();
    lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.None);
    _touchDragTimer.Start();
  }

  void _touchDragTimer_Elapsed(sender, e)
  {
    _touchDragTimer.Stop();

    Dispatcher.Invoke(
      () =>
      {
        lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both);
      });
  }

With this code, you can drag the view around as much as you want, but if you want to drag an item, tap it once to select it, and then you have a brief interval within which to start a drag operation. Let it sit, and it reverts to scrolly behaviour.

I haven't investigated whether this would be easy to integrate directly into GongSolutions.Wpf.DragDrop, but maybe someone might find it useful (or be able to tell me why I shouldn't be doing it! :-D).

I tried this but this part lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both); throws an error for me

An object reference is required for non static field 'ScrollViewer.PanningMode'

I tried this but this part lstItems.SetValue(ScrollViewer.PanningMode, PanningMode.Both); throws an error for me

An object reference is required for non static field 'ScrollViewer.PanningMode'

Use ScrollViewer.PanningModeProperty instead.

Oops, yes, sorry about that, 'twas a typo. 😳

I changed the code a little. Instead of changing the PanningMode on the SelectionChanged event, I have it on PreviewTouchDown, this way the drag is instant rather than having to select the item and then drag it.

private void list_PreviewTouchDown(object sender, System.Windows.Input.TouchEventArgs e)
{
            _touchDragTimer.Stop();
            lst_scheduled.SetValue(ScrollViewer.PanningModeProperty, PanningMode.None);
            _touchDragTimer.Start();
}

I changed the code a little. Instead of changing the PanningMode on the SelectionChanged event, I have it on PreviewTouchDown, this way the drag is instant rather than having to select the item and then drag it.

But then you're not doing the double-tap-and-drag gesture any more, are you?

Indeed, how do you scroll the item's container? With that change, why even have different panning modes? You could just leave it permanently set to None, couldn't you?

Indeed, how do you scroll the item's container? With that change, why even have different panning modes? You could just leave it permanently set to None, couldn't you?

Yes, you are right. When I tested initially there were only a couple items in the box :( I just want a smooth drag without the double tap. Maybe a hold and drag would do.

Was this page helpful?
0 / 5 - 0 ratings