C# 使用PangestureRecognitizer的表单-在UWP上移出窗口区域不会触发状态取消或完成
我的问题是关于Xamarin.Forms上的PangestureRecognitor,特别是UWP上的。平移手势效果很好,菜单会滑入滑出,但如果将鼠标光标移到应用程序窗口之外,则不会触发GestureStatus.Cancelled或GestureStatus.Completed。我简化了下面的代码,因为它并不重要。平移手势工作正常,菜单随平移滑入滑出。问题是,如果将光标移到应用程序窗口之外,它不会触发任何内容 代码如下: panContainer是一个简单的ContentViewC# 使用PangestureRecognitizer的表单-在UWP上移出窗口区域不会触发状态取消或完成,c#,uwp,xamarin.forms,uipangesturerecognizer,C#,Uwp,Xamarin.forms,Uipangesturerecognizer,我的问题是关于Xamarin.Forms上的PangestureRecognitor,特别是UWP上的。平移手势效果很好,菜单会滑入滑出,但如果将鼠标光标移到应用程序窗口之外,则不会触发GestureStatus.Cancelled或GestureStatus.Completed。我简化了下面的代码,因为它并不重要。平移手势工作正常,菜单随平移滑入滑出。问题是,如果将光标移到应用程序窗口之外,它不会触发任何内容 代码如下: panContainer是一个简单的ContentView var pa
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;
}
}
var pangestrue=新的pangestruerecognizer();
pangestrue.PanUpdated+=PanUpdated;
panContainer.GestureRecogeners.Add(panGesture);
私有void PanUpdated(对象发送方,PanUpdatedEventArgs e){
开关(如状态类型){
案例手势状态。已启动:
打破
案例手势状态。正在运行:
menuLayout.TranslationX=(float)e.TotalX;
打破
案例管理状态。已完成:
case GestureStatus.Cancelled://我以为这会被调用!
if(menuLayout.TranslationX<100){
Close();
}否则{
Open();
}
打破
}
}
提前谢谢
如果将鼠标光标移到应用程序窗口之外,则不会触发GestureStatus.Cancelled或GestureStatus.Completed。我简化了下面的代码,因为它并不重要。平移手势工作正常,菜单随平移滑入滑出。问题是,如果将光标移到应用程序窗口之外,它不会触发任何内容
我已经测试了你的代码并重现了这个问题。我试图在源代码中找到问题的原因。我找到了
当指针退出
、操作完成
等时,将调用PanComplete
方法,但当指针退出时未调用该方法。然后我尝试在uwp原生项目中测试点退出
和操作完成
事件。两者都工作正常
<Border Width="200" Height="200" Background="Red" PointerEntered="Border_PointerEntered" PointerExited="Border_PointerExited" ManipulationCompleted="Border_ManipulationCompleted"/>
因此,xamarin可能存在一些问题。根据前面的评论,可行的解决方案
//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();
}
}
//共享部分
公共类PanOutsideWindowEffect:路由效果
{
公共事件事件处理程序更新;
公共PanOutsideWindowEffect():基($“{ResolutionGroupName.Organization}.{nameof(PanOutsideWindowEffect)}”)
{
}
公共无效SendPanCancel()
{
PanUpdated?.Invoke(这是新的PanUpdatedEventArgs(GestureStatus.cancelled,0));
}
}
//超宽带部分
公共类PanOutsideWindowEffect:PlatformEffect
{
私有框架元素框架元素;
私人手机app.Effects.panoutsidewindoweffects;
受保护的覆盖无效附加()
{
frameworkElement=Control==null?容器:控件;
effect=(MobileApp.Effects.PanOutsideWindowEffect)Element.Effects.First(e=>e是MobileApp.Effects.PanOutsideWindowEffect);
if(frameworkElement!=null)
{
frameworkElement.PointerExited+=OnPointerExited;
}
}
受保护的覆盖无效OnDetached()
{
if(frameworkElement!=null)
{
frameworkElement.PointerExit-=OnPointerExit;
}
}
私有void OnPointerExited(对象发送方,PointerRoutedEventArgs args args)
{
效果?.SendPanCancel();
}
}
谢谢您的回复。
//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();
}
}