Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch Screen & Blocking Drop Handlers #135

Closed
alanisaac opened this issue May 28, 2015 · 0 comments · Fixed by #356
Closed

Touch Screen & Blocking Drop Handlers #135

alanisaac opened this issue May 28, 2015 · 0 comments · Fixed by #356
Labels
Milestone

Comments

@alanisaac
Copy link

I'm working with the drag/drop library on a Surface Pro, trying to use a Stylus. The Stylus events get correctly translated into Mouse Events, and are handled by the library appropriately.

However, in my viewmodel that handles the IDropTarget, I attempt to pop open a dialog, with a basic Window.ShowDialog() call. When I use a mouse, this works fine. But when I use a stylus (or touch), the newly opened dialog is unable to respond to stylus (or touch) events.

I believe this is the same issue noted here: http://stackoverflow.com/questions/21178504/touch-events-not-working-after-dodragdrop

And I think the solution is the same as the one here: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/d9e4335b-beaa-4ecf-abd6-a900af8a9e41/show-a-dialog-inside-touchup-event?forum=wpf

The idea being that for stylus/touch events, the handler needs to return first before other UI-blocking events are invoked. The way I solved this in my own pull of the code is to make the view model code invoke asynchronously. I made the following change in DragDrop.cs:

private static void DropTarget_PreviewDrop(object sender, DragEventArgs e)
{
      var dropInfo = new DropInfo(sender, e, m_DragInfo);
      var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement);
      var dragHandler = TryGetDragHandler(m_DragInfo, sender as UIElement);

      DragAdorner = null;
      EffectAdorner = null;
      DropTargetAdorner = null;

      dropHandler.DragOver(dropInfo);
      dropHandler.Drop(dropInfo);
      dragHandler.Dropped(dropInfo);

      Mouse.OverrideCursor = null;
      e.Handled = !dropInfo.NotHandled;
}

To

private static async void DropTarget_PreviewDrop(object sender, DragEventArgs e)
{
      var dropInfo = new DropInfo(sender, e, m_DragInfo);
      var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement);
      var dragHandler = TryGetDragHandler(m_DragInfo, sender as UIElement);

      DragAdorner = null;
      EffectAdorner = null;
      DropTargetAdorner = null;
      Mouse.OverrideCursor = null;

      await Dispatcher.CurrentDispatcher.InvokeAsync(() => 
    {
      dropHandler.DragOver(dropInfo);
      dropHandler.Drop(dropInfo);
      dragHandler.Dropped(dropInfo);
    });

      e.Handled = !dropInfo.NotHandled;
}

This appears to allow the desired behavior, though I am not currently testing whether setting e.Handled after an await call works as expected. It does make use of async/await, so it may not be viable for the overall solution, but maybe something similar can be incorporated in the future.

@punker76 punker76 added the Bug label Oct 17, 2020
@punker76 punker76 added this to the 2.3.0 milestone Oct 17, 2020
@punker76 punker76 linked a pull request Oct 17, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants