Xamarin.Forms using PanGestureRecognizer - move outside of Window area on UWP does not trigger Status Canceled or Completed

Viewed 1440

My question is regarding the PanGestureRecognizer on Xamarin.Forms, specifically on UWP. The pan gesture works great and the menu slides in and out but if you move the mouse cursor outside of the application window it does not trigger GestureStatus.Canceled, or GestureStatus.Completed. I've simplified the code below because it is not important. The pan gesture is working correctly and the menu is sliding in and out with the pan. The issue is it is not triggering anything if you move the cursor outside of the app window.

Code below:

panContainer is a simple ContentView.

var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += PanUpdated;
panContainer.GestureRecognizers.Add(panGesture);

private void PanUpdated(object sender,PanUpdatedEventArgs e) {
        switch(e.StatusType) {
            case GestureStatus.Started:
                break;
            case GestureStatus.Running:
                menuLayout.TranslationX = (float)e.TotalX;
                break;
            case GestureStatus.Completed:
            case GestureStatus.Canceled:  //I assumed this would be called!
                if(menuLayout.TranslationX < 100) {
                    Close();
                } else {
                    Open();
                }
                break;
        }
    }

Thanks in advance!

2 Answers

Workable solution based on the previous comment

//Shared part
public class PanOutsideWindowEffect : RoutingEffect
{
    public event EventHandler<PanUpdatedEventArgs> PanUpdated;

    public PanOutsideWindowEffect() : base($"{ResolutionGroupName.Organization}.{nameof(PanOutsideWindowEffect)}")
    {
    }

    public void SendPanCancel()
    {
        PanUpdated?.Invoke(this, new PanUpdatedEventArgs(GestureStatus.Canceled, 0));
    }
}

//UWP part
public class PanOutsideWindowEffect : PlatformEffect
{
    private FrameworkElement frameworkElement;
    private MobileApp.Effects.PanOutsideWindowEffect effect;

    protected override void OnAttached()
    {
        frameworkElement = Control == null ? Container : Control;
        effect = (MobileApp.Effects.PanOutsideWindowEffect)Element.Effects.First(e => e is MobileApp.Effects.PanOutsideWindowEffect);

        if (frameworkElement != null)
        {
            frameworkElement.PointerExited += OnPointerExited;
        }
    }

    protected override void OnDetached()
    {
        if (frameworkElement != null)
        {
            frameworkElement.PointerExited -= OnPointerExited;
        }
    }

    private void OnPointerExited(object sender, PointerRoutedEventArgs args)
    {
        effect?.SendPanCancel();
    }
}
Related