• 与众不同 windows phone (25) Input(输入)之捕获 UIElement 之外的触控操作, Silverlight 方式捕获手势操作, XNA 方式捕获手势操作, 多点触控


    [索引页]
    [源码下载]


    与众不同 windows phone (25) - Input(输入)之捕获 UIElement 之外的触控操作, Silverlight 方式捕获手势操作, XNA 方式捕获手势操作, 多点触控



    作者:webabcd


    介绍
    与众不同 windows phone 7.5 (sdk 7.1) 之输入

    • 捕获 UIElement 之外的触控操作
    • Silverlight 方式捕获手势操作
    • XNA 方式捕获手势操作
    • 多点触控



    示例
    1、演示如何捕获 UIElement 之外的触控操作
    OutsideCapture.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Input.Touch.OutsideCapture"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            
            <Rectangle Name="rect" Width="100" Height="100" Fill="Red" 
                       MouseLeftButtonDown="rect_MouseLeftButtonDown" 
                       MouseLeftButtonUp="rect_MouseLeftButtonUp"
                       MouseMove="rect_MouseMove" />
    
            <TextBlock Name="lblMsg" VerticalAlignment="Top" TextWrapping="Wrap" Text="用手指触摸红色方块,然后将手指移除红色方块区域" />
            
        </Grid>
        
    </phone:PhoneApplicationPage>

    OutsideCapture.xaml.cs

    /*
     * 演示如何在 UIElement 外响应 UIElement 上的触控事件
     * 
     * UIElement - UI 元素
     *     CaptureMouse() - 捕获外部触摸事件,这样即使触摸事件在 UIElement 之外也可以响应
     *     ReleaseMouseCapture() - 取消外部触摸事件的捕获
     *     
     * 注:
     * 调用 UIElement 的 CaptureMouse() 方法需要满足以下条件
     * 1、当前没有任何 UIElement 正在捕获中
     * 2、必须在 UIElement 的 MouseLeftButtonDown 事件中调用 CaptureMouse() 方法
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace Demo.Input.Touch
    {
        public partial class OutsideCapture : PhoneApplicationPage
        {
            public OutsideCapture()
            {
                InitializeComponent();
            }
    
            private void rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                rect.CaptureMouse();
    
                lblMsg.Text = "触摸点坐标为:" + e.GetPosition(LayoutRoot).ToString();
            }
    
            private void rect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                rect.ReleaseMouseCapture();
            }
    
            private void rect_MouseMove(object sender, MouseEventArgs e)
            {
                // 调用了 rect.CaptureMouse() 之后,即使触控移出 rect 也可以响应触控事件
                lblMsg.Text = "触摸点坐标为:" + e.GetPosition(LayoutRoot).ToString();
            }
        }
    }


    2、演示如何通过 Silverlight 捕获手势操作
    ManipulationDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Input.Touch.ManipulationDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
                
                <TextBlock Text="请随便做一些手势操作,以查看演示效果" />
                
                <TextBlock Name="lblMsg" />
                
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    ManipulationDemo.xaml.cs

    /*
     * 演示如何在 Silverlight 下捕获手势操作
     * 
     * UIElement - UI 元素
     *     ManipulationStarted - 手势操作开始时触发的事件,即触摸屏幕时触发的事件(事件参数:ManipulationStartedEventArgs)
     *     ManipulationDelta - 手势操作过程中触发的事件(事件参数:ManipulationDeltaEventArgs)
     *     ManipulationCompleted - 手持操作完成时触发的事件(事件参数:ManipulationCompletedEventArgs)
     *     
     * 
     * ManipulationStartedEventArgs
     *     ManipulationContainer - 手势操作的容器,即坐标的参照物
     *     ManipulationOrigin - 手势起始点坐标
     *     Complete() - 停止捕获手势操作,即不会再触发 ManipulationDelta 事件
     * 
     * ManipulationDeltaEventArgs
     *     ManipulationContainer - 手势操作的容器,即坐标的参照物
     *     ManipulationOrigin - 当前手势的中心点坐标
     *     Complete() - 停止捕获手势操作,即不会再触发 ManipulationDelta 事件
     *     DeltaManipulation.Scale - 最近一次缩放比的变化
     *     DeltaManipulation.Translation - 最近一次位移的变化
     *     CumulativeManipulation.Scale - 缩放比的累计的变化
     *     CumulativeManipulation.Translation - 位移的累计的变化
     * 
     * ManipulationCompletedEventArgs
     *     ManipulationContainer - 手势操作的容器,即坐标的参照物
     *     ManipulationOrigin - 当前手势的中心点坐标
     *     TotalManipulation.Scale - 缩放比的总计变化
     *     TotalManipulation.Translation - 位移的总计变化
     *     IsInertial - 手势操作收尾时是否有惯性
     *     FinalVelocities.LinearVelocity - 如果手势操作收尾时有惯性,则此属性会返回其线性速度
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace Demo.Input.Touch
    {
        public partial class ManipulationDemo : PhoneApplicationPage
        {
            public ManipulationDemo()
            {
                InitializeComponent();
                
                // 注册相关手势事件
                LayoutRoot.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(LayoutRoot_ManipulationStarted);
                LayoutRoot.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(LayoutRoot_ManipulationDelta);
                LayoutRoot.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(LayoutRoot_ManipulationCompleted);
            }
    
            void LayoutRoot_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
            {
                lblMsg.Text = string.Format("手势起始点坐标 - x: {0},y: {1}", e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
            }
    
            void LayoutRoot_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
            {
                lblMsg.Text = string.Format("当前手势的中心点坐标 - x: {0},y: {1}", e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "缩放比最近的变化:" + e.DeltaManipulation.Scale.ToString();
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "位移最近的变化" + e.DeltaManipulation.Translation.ToString();
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "缩放比总共的变化:" + e.CumulativeManipulation.Scale.ToString();
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "位移总共的变化:" + e.CumulativeManipulation.Translation.ToString();
                lblMsg.Text += Environment.NewLine;
            }
    
            void LayoutRoot_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
            {
                lblMsg.Text = string.Format("当前手势的中心点坐标 - x: {0},y: {1}", e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "缩放比总共的变化:" + e.TotalManipulation.Scale.ToString();
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "位移总共的变化:" + e.TotalManipulation.Translation.ToString();
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "手势操作收尾时是否有惯性:" + e.IsInertial.ToString();
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "如果手势操作收尾时有惯性,其速度为:" + e.FinalVelocities.LinearVelocity.ToString();
            }
        }
    }


    3、演示如何通过 XNA 捕获手势操作
    XNAGesture.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Input.Touch.XNAGesture"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <TextBlock Text="请随便做一些手势操作,以查看演示效果" />
    
                <TextBlock Name="lblMsg" TextWrapping="Wrap" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    XNAGesture.xaml.cs

    /*
     * 演示如何在 XNA 下捕获手势操作
     * 
     * TouchPanel - 触摸面板
     *     DisplayOrientation - 显示方向(Microsoft.Xna.Framework.DisplayOrientation 枚举)
     *         Default, LandscapeLeft, LandscapeRight, Portrait
     *     DisplayWidth - 宽
     *     DisplayHeight - 高
     *     IsGestureAvailable - 当前是否存在有效的手势操作
     *     EnabledGestures - 指定需要捕获的手势操作类型(Microsoft.Xna.Framework.Input.Touch.GestureType 枚举)
     *         None, Tap, DoubleTap, Hold, HorizontalDrag, VerticalDrag, FreeDrag, Pinch, Flick, DragComplete, PinchComplete
     *     GetCapabilities() - 返回 TouchPanelCapabilities 类型对象
     *     ReadGesture() - 返回 GestureSample 类型对象
     *     
     * 
     * TouchPanelCapabilities - 触摸板的能力
     *     IsConnected - 触摸板是否有效
     *     MaximumTouchCount - 触摸板可以同时捕获的最大点数,即最大支持几点触摸
     *     
     * GestureSample - 手势信息
     *     GestureType - 手势操作类型
     *     Position - 两点手势操作时,第一点的位置
     *     Position2 - 两点手势操作时,第二点的位置
     *     Delta - 两点手势操作时,第一点的位移的最近变化值
     *     Delta2  - 两点手势操作时,第二点的位移的最近变化值
     *     Timestamp - 此手势开始的时间戳(此值为系统自上次启动以来到此手势开始时所经过的时间)
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using Microsoft.Xna.Framework.Input.Touch;
    
    namespace Demo.Input.Touch
    {
        public partial class XNAGesture : PhoneApplicationPage
        {
            public XNAGesture()
            {
                InitializeComponent();
    
                // 在手势操作完成后获取相关的手势信息
                LayoutRoot.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(LayoutRoot_ManipulationCompleted);
    
                TouchPanelCapabilities tpc = TouchPanel.GetCapabilities();
                lblMsg.Text = "触摸板是否有效:" + tpc.IsConnected;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "触摸板最大支持 " + tpc.MaximumTouchCount + " 点触摸";
                lblMsg.Text += Environment.NewLine;
    
                // 指定需要捕获的手势类型(只有指定的类型才能捕获到)
                TouchPanel.EnabledGestures = GestureType.Tap | GestureType.DoubleTap | GestureType.Hold | GestureType.HorizontalDrag | GestureType.VerticalDrag | GestureType.FreeDrag | GestureType.Pinch | GestureType.Flick | GestureType.DragComplete | GestureType.PinchComplete;
            }
    
            // 当一次手势操作完成后,获取此次手势操作包含的全部手势信息
            void LayoutRoot_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
            {
                /*
                 * 由于一次手势操作可能会有多个手势信息,所以这里要一直输出手势信息直至没有有效的手势为止
                 * 这里的一次手势操作指的是手指按下到抬起后,这期间可能会有多个手势信息(比如一次手势操作可能会由多个水平移动、多个垂直移动等组成)
                 * 可以在每一帧当 TouchPanel.IsGestureAvailable 有效时都获取一下 TouchPanel.ReadGesture(),这样就可以即时获取到当前手势信息
                 */
                while (TouchPanel.IsGestureAvailable)
                {
                    GestureSample gs = TouchPanel.ReadGesture();
    
                    lblMsg.Text += gs.GestureType.ToString() + ",";
                }
            }
        }
    }


    4、演示如何响应多点触控
    MutiTouch.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Input.Touch.MutiTouch"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
                
                <TextBlock Text="请多点触摸此屏幕,以查看演示效果" />
                
                <TextBlock Name="lblMsg" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    MutiTouch.xaml.cs

    /*
     * 演示系统对多点触摸的支持
     * 
     * 
     * TouchPanel - 触摸面板
     *     GetState() - 返回触摸面板上,被触摸的所有点的状态(TouchCollection 类型)
     * 
     * TouchCollection - 触摸点的集合(TouchLocation 的集合)
     * 
     * TouchLocation - 触摸点
     *     Position - 触摸点的坐标
     *     State - 触摸点的状态(TouchLocationState 类型)
     *     
     * TouchLocationState - 触摸点状态(Microsoft.Xna.Framework.Input.Touch.TouchLocationState 枚举)
     *     Invalid - 无效
     *     Released - 被释放
     *     Pressed - 被触摸,即一个新的触摸点
     *     Moved - 被触摸后移动
     *     
     * 
     * 注:目前只支持 4 点触摸
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using System.Windows.Navigation;
    using Microsoft.Xna.Framework.Input.Touch;
    
    namespace Demo.Input.Touch
    {
        public partial class MutiTouch : PhoneApplicationPage
        {
            public MutiTouch()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
            }
    
            void CompositionTarget_Rendering(object sender, EventArgs e)
            {
                this.Dispatcher.BeginInvoke(delegate
                {
                    lblMsg.Text = "";
                });
    
                // 获取当前触摸点集合
                TouchCollection touchLocations = TouchPanel.GetState();
                for (int i = 0; i < touchLocations.Count; i++)
                {
                    TouchLocation touchLocation = touchLocations[i];
    
                    float x = touchLocation.Position.X;
                    float y = touchLocation.Position.Y;
    
                    // 显示每个触摸点的坐标及状态
                    this.Dispatcher.BeginInvoke(new InvokeUIWidthParameterDelegate(ShowMessage), i, x, y, touchLocation.State);
                }
            }
    
            void ShowMessage(int i, float x, float y, TouchLocationState state)
            {
                lblMsg.Text += string.Format("触摸点{0}坐标 - X: {1},Y: {2},状态: {3}", i, x, y, state.ToString());
                lblMsg.Text += Environment.NewLine;
            }
    
            private delegate void InvokeUIWidthParameterDelegate(int i, float x, float y, TouchLocationState state);
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    OC基础5-NSString
    OC基础4
    OC基础3
    使用顺序表建立一个简单的学生管理系统
    二叉树的创建,遍历以及叶子结点数
    本地IP和主机IP
    双向链表的删除
    双向链表的查找及插入
    双向循环链表的建立
    单链表的合并
  • 原文地址:https://www.cnblogs.com/webabcd/p/2657968.html
Copyright © 2020-2023  润新知