WP7:由Silverlight处理时抑制XNA触摸输入?

WP7:由Silverlight处理时抑制XNA触摸输入?,silverlight,xna,windows-phone-7,windows-phone-7.1,Silverlight,Xna,Windows Phone 7,Windows Phone 7.1,我有一个芒果版的XNA+Silverlight游戏:主要是XNA,上面有一些Silverlight用户界面。我遇到的问题是,当你按下按钮或与Silverlight控件交互时,触摸信息仍然会传递到XNA游戏循环。如何抑制这种情况?由于XNA的互操作方式,您将始终获得由XNA和Silverlight处理的触摸输入-在某种程度上,XNA获得优先权,因此Silverlight将在此基础上发挥作用。如果您需要忽略特定的手势位置(例如Silverlight按钮所在的位置),您可以检查手势位置: if (To

我有一个芒果版的XNA+Silverlight游戏:主要是XNA,上面有一些Silverlight用户界面。我遇到的问题是,当你按下按钮或与Silverlight控件交互时,触摸信息仍然会传递到XNA游戏循环。如何抑制这种情况?

由于XNA的互操作方式,您将始终获得由XNA和Silverlight处理的触摸输入-在某种程度上,XNA获得优先权,因此Silverlight将在此基础上发挥作用。如果您需要忽略特定的手势位置(例如Silverlight按钮所在的位置),您可以检查手势位置:

if (TouchPanel.IsGestureAvailable)
{
    if (TouchPanel.ReadGesture().GestureType == GestureType.Tap)
    {
        if (TouchPanel.ReadGesture().Position == new Vector2(120, 120))
        {

        }
    }
}

写了一个类来为我做跟踪。页面加载后(在加载的处理程序中),创建该页面并为其提供根元素(以便它可以附加到LayoutUpdated事件)。注册在游戏过程中可能覆盖游戏表面的任何控件。然后,只需调用touchecontrol并在touch位置传递,以确定是否应忽略该点。它缓存控件的区域,并在布局更新时进行更新

应适用于矩形图元的移动、更改大小或折叠/展开

public class ControlTouchTracker
{
    private List<FrameworkElement> controls = new List<FrameworkElement>();
    private Dictionary<FrameworkElement, ControlRegion> controlBounds = new Dictionary<FrameworkElement, ControlRegion>();

    public ControlTouchTracker(FrameworkElement rootElement)
    {
        rootElement.LayoutUpdated += this.OnLayoutUpdated;
    }

    public void RegisterControl(FrameworkElement control)
    {
        controls.Add(control);
    }

    public void RemoveControl(FrameworkElement control)
    {
        controls.Remove(control);
        controlBounds.Remove(control);
    }

    private void OnLayoutUpdated(object sender, EventArgs e)
    {
        foreach (Control control in this.controls)
        {
            this.RefreshControlBounds(control);
        }
    }

    private void RefreshControlBounds(FrameworkElement control)
    {
        if (this.ControlIsVisible(control))
        {
            try
            {
                GeneralTransform controlTransform = control.TransformToVisual(Application.Current.RootVisual);
                Point offset = controlTransform.Transform(new Point(0, 0));

                this.controlBounds[control] = new ControlRegion
                {
                    Left = (float)offset.X,
                    Right = (float)(offset.X + control.ActualWidth),
                    Top = (float)offset.Y,
                    Bottom = (float)(offset.Y + control.ActualHeight)
                };
            }
            catch (ArgumentException)
            {
            }
        }
        else
        {
            if (this.controlBounds.ContainsKey(control))
            {
                this.controlBounds.Remove(control);
            }
        }
    }

    private bool ControlIsVisible(FrameworkElement control)
    {
        // End case
        if (control == null)
        {
            return true;
        }

        if (control.Visibility == Visibility.Collapsed)
        {
            return false;
        }

        return this.ControlIsVisible(control.Parent as FrameworkElement);
    }

    public bool TouchesControl(Vector2 touchPosition)
    {
        foreach (ControlRegion region in this.controlBounds.Values)
        {
            if (touchPosition.X >= region.Left && touchPosition.X <= region.Right &&
                touchPosition.Y >= region.Top && touchPosition.Y <= region.Bottom)
            {
                return true;
            }
        }

        return false;
    }

    public class ControlRegion
    {
        public float Left { get; set; }
        public float Right { get; set; }
        public float Top { get; set; }
        public float Bottom { get; set; }
    }
}
公共类ControlTouchTracker
{
私有列表控件=新列表();
私有字典controlBounds=新字典();
公共ControlTouchTracker(FrameworkElement根元素)
{
rootElement.LayoutUpdated+=this.OnLayoutUpdated;
}
公共无效注册表控件(FrameworkElement控件)
{
控件。添加(控件);
}
公共无效移除控件(FrameworkElement控件)
{
控制。移除(控制);
controlBounds.Remove(控件);
}
私有void OnLayoutUpdated(对象发送方,事件参数)
{
foreach(此.controls中的控件)
{
这个.RefreshControlBounds(control);
}
}
私有void RefreshControlBounds(FrameworkElement控件)
{
如果(此.ControlIsVisible(控件))
{
尝试
{
GeneralTransformControlTransform=control.TransformToVisual(Application.Current.RootVisual);
点偏移=controlTransform.Transform(新点(0,0));
this.controlBounds[control]=新的ControlRegion
{
左=(浮点)偏移量.X,
右=(浮动)(偏移量.X+控制点实际宽度),
顶部=(浮动)偏移量.Y,
底部=(浮动)(偏移量.Y+控制.实际高度)
};
}
捕获(异常)
{
}
}
其他的
{
if(this.controlBounds.ContainsKey(control))
{
this.controlBounds.Remove(控件);
}
}
}
私有布尔控件可见(FrameworkElement控件)
{
//终局
if(control==null)
{
返回true;
}
如果(control.Visibility==Visibility.Collapsed)
{
返回false;
}
返回此.ControlIsVisible(control.Parent作为FrameworkElement);
}
公共布尔触摸控制(矢量2触摸位置)
{
foreach(此.controlBounds.Values中的ControlRegion区域)
{

如果(touchPosition.X>=region.Left&&touchPosition.X=region.Top&&touchPosition.Y为什么标签
windows phone mango
自动解析为
windows-phone-7.1
,如果这不是真正的意义呢?它是同义词。7.1确实是mango(7.5)的SDK版本操作系统。新操作系统的官方名称是7.5。请看:正是我上面提到的。SDK是7.1。操作系统是7.5。通常没有办法解决这个问题?我需要手动维护这些“死区”?也许我可以写一些东西,您可以注册Silverlight控件进行跟踪,它可以告诉您触摸点是否有效(基于控件的位置以及控件是否可见或折叠)。然后XNA循环在处理触摸之前运行此检查。只需为SL控件设置一个特定区域并进行检查。或者,重新考虑在游戏中使用SL控件的方式,以便简单的触摸不会影响此过程。我不想通过封锁一些“Silverlight”来限制我的游戏区域。我将尝试注册它们并自动忽略控件所在区域中的触摸。我最不想看到的是一个错误,我移动了控件,忘记了更新仅魔法silverlight区域。仍在检查位置,但很荣幸-你想到了!