设为首页 收藏本站
查看: 1091|回复: 0

Windows Phone 7 多点触摸编程

[复制链接]

尚未签到

发表于 2015-5-9 06:41:39 | 显示全部楼层 |阅读模式
  一、基本的程序结构
  一个需要响应多点触控的 Silverlight 应用程序必须将一个处理程序连接到静态 Touch.FrameReported 事件:
  Touch.FrameReported += OnTouchFrameReported;
FrameReported 事件是静态 Touch 类的唯一公共成员。处理程序如下所示:
  void OnTouchFrameReported(
  object sender, TouchFrameEventArgs args) {
  ...
}
您可以在应用程序中安装多个 Touch.FrameReported 事件处理程序,所有这些事件处理程序都会报告应用程序中任何位置的所有触控事件。
  二、事件传入参数TouchFrameEventArgs
  TouchFrameEventArgs 有一个名为 TimeStamp 的公共属性(我还没有机会使用)和三个重要的公共方法:
  TouchPoint GetPrimaryTouchPoint(UIElement relativeTo)
TouchPointCollection GetTouchPoints(UIElement relativeTo)
void SuspendMousePromotionUntilTouchUp()
GetPrimaryTouchPoint 或 GetTouchPoints 的参数仅用于报告 TouchPoint 对象的位置信息。您可以将空值用于此参数,位置信息相对于整个 Silverlight 应用程序的左上角。
  多点触控支持多个手指同时触摸屏幕,触摸屏幕的每个手指(数量存在上限,当前通常为两个)都是一个触摸点。主要触摸点是指在没有其他手指触摸屏幕并且未按下鼠标按钮时触摸屏幕的手指。用一个手指触摸屏幕。这是主要触摸点。
  在第一个手指仍触摸着屏幕时,将第二个手指放在屏幕上。很显然,第二手指不是主要触摸点。但现在仍将第二个手指放在屏幕上,抬起第一个手指,然后再将其放回到屏幕上。这是主要触摸点吗?不,都不是。仅当没有其他手指触摸屏幕时,才会出现主要触摸点。
  在实际的多点触控应用程序中,您应该注意不要依赖主要触摸点,因为用户通常不会重视第一次触摸的特定意义。仅为实际触摸屏幕的手指激发事件。对非常接近屏幕但并未触摸屏幕的手指,不会进行悬停检测。
  基于一个触摸点或多个触摸点激发一个特殊的 Touch.FrameReported 事件。从 GetTouchPoints 方法返回的 TouchPointCollection 包含与特定事件关联的所有触摸点。从 GetPrimaryTouchPoint 返回的 TouchPoint 始终是一个主要触摸点。如果没有与该特定事件关联的主要触摸点,GetPrimaryTouchPoint 将返回 null。即使从 GetPrimaryTouchPoint 返回的 TouchPoint 不是 null,它也不会与从 GetTouchPoints 返回的其中一个 TouchPoint 对象是相同对象,但在传递给这些方法的参数相同时所有属性将相同。
  TouchPoint 类定义以下四个只读属性,这些属性都由依赖属性支持:
  Action 属性,类型为 TouchAction(一个具有 Down、Move 和 Up 成员的枚举)。
Position 属性,类型为 Point,它相对于作为参数传递给 GetPrimaryTouchPoint 或 GetTouchPoints 方法的元素(或相对于参数为 null 的应用程序的左上角)。
Size 属性,类型为 Size。
  TouchDevice 属性,类型为 TouchDevice。
  TouchDevice 对象具有两个也由依赖属性支持的只读属性:
  DirectlyOver 属性,类型为 DirectlyOver(手指下最上面的元素)。
Id 属性,类型为 int。
DirectlyOver 不必是传递给 GetPrimaryTouchPoint 或 GetTouchPoints 的元素的子项。如果手指在 Silverlight 应用程序内(由 Silverlight 插件对象的尺寸定义),但不在可点击测试控件覆盖的范围内,则此属性可以为空。(具有空背景刷的面板不可点击测试。)
  若要在多个手指之间区分,ID 属性至关重要。在特定手指触摸屏幕时,与该手指关联的一系列特定事件总是以 Down 操作开始,接着是 Move 事件,最后是 Up 事件。所有这些事件都将与相同的 ID 关联。(但不要以为主要触摸点的 ID 值将为 0 或 1。)
  大多数重要的多点触控代码都会使用 Dictionary 集合,其中 TouchDevice 的 ID 属性是字典键。这是跨事件存储特定手指信息的方式。
  三、涂鸦板例子
  涂鸦板例子 综合运用ApplicationBar菜单、多点触摸和IsolatedStorageFile本地存储
DSC0000.jpg DSC0001.jpg DSC0002.jpg
  xaml


DSC0003.gif DSC0004.gif View Code




   
   
        
            
            
        
        
        
            
            
        
        
            
        
   
   
        
            
            
            
            
            
            
            
               
               
               
               
            
        
   

  cs


View Code



using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace Jot
{
    public partial class MainPage : PhoneApplicationPage
    {
        JotAppSettings appSettings = (Application.Current as App).AppSettings;
        Dictionary activeStrokes = new Dictionary();
        public MainPage()
        {
            InitializeComponent();
            inkPresenter.Strokes = appSettings.StrokeCollections[appSettings.PageNumber];
            inkPresenter.Background = new SolidColorBrush(appSettings.Background);
            // Re-assign ApplicationBar button names
            appbarLastButton = this.ApplicationBar.Buttons[1] as ApplicationBarIconButton;
            appbarNextButton = this.ApplicationBar.Buttons[2] as ApplicationBarIconButton;
            appbarDeleteButton = this.ApplicationBar.Buttons[3] as ApplicationBarIconButton;
            TitleAndAppbarUpdate();
            Touch.FrameReported += OnTouchFrameReported;
            //一个需要响应多点触控的 Silverlight 应用程序必须将一个处理程序连接到静态 Touch.FrameReported 事件
        }
        //处理多点触摸事件
        void OnTouchFrameReported(object sender, TouchFrameEventArgs args)
        {
            TouchPoint primaryTouchPoint = args.GetPrimaryTouchPoint(null);
            if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down)
                args.SuspendMousePromotionUntilTouchUp();
            /*
             * foreach 循环枚举从 GetTouchPoints 返回的 TouchPointCollection 的 TouchPoint 成员。
             * (您会希望多点触控感知 Silverlight 程序能处理多个手指,但您不会希望它在检测到太多手指时出现故障!)ID 将添加到 Down 事件的字典中,然后从 Up 事件的字典中删除。
             * */
            TouchPointCollection touchPoints = args.GetTouchPoints(inkPresenter);
            foreach (TouchPoint touchPoint in touchPoints)
            {
                Point pt = touchPoint.Position;
                int id = touchPoint.TouchDevice.Id;
                switch (touchPoint.Action)
                {
                    case TouchAction.Down:
                        Stroke stroke = new Stroke();
                        stroke.DrawingAttributes.Color = appSettings.Foreground;
                        stroke.DrawingAttributes.Height = appSettings.StrokeWidth;
                        stroke.DrawingAttributes.Width = appSettings.StrokeWidth;
                        stroke.StylusPoints.Add(new StylusPoint(pt.X, pt.Y));
                        inkPresenter.Strokes.Add(stroke);
                        activeStrokes.Add(id, stroke);
                        break;
                    case TouchAction.Move:
                        activeStrokes[id].StylusPoints.Add(new StylusPoint(pt.X, pt.Y));
                        break;
                    case TouchAction.Up:
                        activeStrokes[id].StylusPoints.Add(new StylusPoint(pt.X, pt.Y));
                        activeStrokes.Remove(id);
                        TitleAndAppbarUpdate();
                        break;
                }
            }
        }
        //新增一个页面
        void OnAppbarAddClick(object sender, EventArgs args)
        {
            StrokeCollection strokes = new StrokeCollection();
            appSettings.PageNumber += 1;
            appSettings.StrokeCollections.Insert(appSettings.PageNumber, strokes);
            inkPresenter.Strokes = strokes;
            TitleAndAppbarUpdate();
        }
        //上一个页面
        void OnAppbarLastClick(object sender, EventArgs args)
        {
            appSettings.PageNumber -= 1;
            inkPresenter.Strokes = appSettings.StrokeCollections[appSettings.PageNumber];
            TitleAndAppbarUpdate();
        }
        //下一个页面
        void OnAppbarNextClick(object sender, EventArgs args)
        {
            appSettings.PageNumber += 1;
            inkPresenter.Strokes = appSettings.StrokeCollections[appSettings.PageNumber];
            TitleAndAppbarUpdate();
        }
        //删除当前的页面
        void OnAppbarDeleteClick(object sender, EventArgs args)
        {
            MessageBoxResult result = MessageBox.Show("Delete this page?", "Jot",
                                                       MessageBoxButton.OKCancel);
            if (result == MessageBoxResult.OK)
            {
                if (appSettings.StrokeCollections.Count == 1)
                {
                    appSettings.StrokeCollections[0].Clear();
                }
                else
                {
                    appSettings.StrokeCollections.RemoveAt(appSettings.PageNumber);
                    if (appSettings.PageNumber == appSettings.StrokeCollections.Count)
                        appSettings.PageNumber -= 1;
                    inkPresenter.Strokes = appSettings.StrokeCollections[appSettings.PageNumber];
                }
                TitleAndAppbarUpdate();
            }
        }
        //设置画笔背景颜色
        void OnAppbarSwapColorsClick(object sender, EventArgs args)
        {
            Color foreground = appSettings.Background;
            appSettings.Background = appSettings.Foreground;
            appSettings.Foreground = foreground;
            inkPresenter.Background = new SolidColorBrush(appSettings.Background);
            foreach (StrokeCollection strokeCollection in appSettings.StrokeCollections)
                foreach (Stroke stroke in strokeCollection)
                    stroke.DrawingAttributes.Color = appSettings.Foreground;
        }
        //设置画笔的粗细
        void OnAppbarSetStrokeWidthClick(object sender, EventArgs args)
        {
            ApplicationBarMenuItem item = sender as ApplicationBarMenuItem;
            if (item.Text.StartsWith("light"))
                appSettings.StrokeWidth = 1;
            else if (item.Text.StartsWith("medium"))
                appSettings.StrokeWidth = 3;
            else if (item.Text.StartsWith("heavy"))
                appSettings.StrokeWidth = 5;
        }
        void TitleAndAppbarUpdate()
        {
            pageInfoTitle.Text = String.Format(" - PAGE {0} OF {1}",
                                               appSettings.PageNumber + 1,
                                               appSettings.StrokeCollections.Count);
            appbarLastButton.IsEnabled = appSettings.PageNumber > 0;
            appbarNextButton.IsEnabled =
                        appSettings.PageNumber < appSettings.StrokeCollections.Count - 1;
            appbarDeleteButton.IsEnabled = (appSettings.StrokeCollections.Count > 1) ||
                                           (appSettings.StrokeCollections[0].Count > 0);
        }
    }
}
  本地存储功能封装的类


View Code



using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Media;
using System.Xml.Serialization;
namespace Jot
{
    public class JotAppSettings
    {
        public JotAppSettings()
        {
            this.PageNumber = 0;
            this.Foreground = (Color)Application.Current.Resources["PhoneForegroundColor"];
            this.Background = (Color)Application.Current.Resources["PhoneBackgroundColor"];
            this.StrokeWidth = 3;
        }
        // Public properties -- the actual application settins
        public List StrokeCollections { get; set; }
        public int PageNumber { set; get; }
        public Color Foreground { set; get; }
        public Color Background { set; get; }
        public int StrokeWidth { set; get; }
        public static JotAppSettings Load()
        {
            JotAppSettings settings;
            IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
            if (iso.FileExists("settings.xml"))
            {
                IsolatedStorageFileStream stream = iso.OpenFile("settings.xml", FileMode.Open);
                StreamReader reader = new StreamReader(stream);
                XmlSerializer ser = new XmlSerializer(typeof(JotAppSettings));
                settings = ser.Deserialize(reader) as JotAppSettings;
                reader.Close();
            }
            else
            {
                // Create and initialize new JotAppSettings object
                settings = new JotAppSettings();
                settings.StrokeCollections = new List();
                settings.StrokeCollections.Add(new StrokeCollection());
            }
            iso.Dispose();
            return settings;
        }
        public void Save()
        {
            IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
            IsolatedStorageFileStream stream = iso.CreateFile("settings.xml");
            StreamWriter writer = new StreamWriter(stream);
            XmlSerializer ser = new XmlSerializer(typeof(JotAppSettings));
            ser.Serialize(writer, this);
            writer.Close();
            iso.Dispose();
        }
    }
}
  app.xaml


View Code




   
   
   
   
        
        
   

  app.xaml.cs


View Code



using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace Jot
{
    public partial class App : Application
    {
        // Application Settings
        public JotAppSettings AppSettings { set; get; }
        // Easy access to the root frame
        public PhoneApplicationFrame RootFrame { get; private set; }
        // Constructor
        public App()
        {
            // Global handler for uncaught exceptions.
            // Note that exceptions thrown by ApplicationBarItem.Click will not get caught here.
            UnhandledException += Application_UnhandledException;
            // Standard Silverlight initialization
            InitializeComponent();
            // Phone-specific initialization
            InitializePhoneApplication();
        }
        // Code to execute when the application is launching (eg, from Start)
        // This code will not execute when the application is reactivated
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
            AppSettings = JotAppSettings.Load();
        }
        // Code to execute when the application is activated (brought to foreground)
        // This code will not execute when the application is first launched
        private void Application_Activated(object sender, ActivatedEventArgs e)
        {
            AppSettings = JotAppSettings.Load();
        }
        // Code to execute when the application is deactivated (sent to background)
        // This code will not execute when the application is closing
        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
            AppSettings.Save();
        }
        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
            AppSettings.Save();
        }
        // Code to execute if a navigation fails
        void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // A navigation has failed; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }
        // Code to execute on Unhandled Exceptions
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }
        #region Phone application initialization
        // Avoid double-initialization
        private bool phoneApplicationInitialized = false;
        // Do not add any additional code to this method
        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;
            // Create the frame but don't set it as RootVisual yet; this allows the splash
            // screen to remain active until the application is ready to render.
            RootFrame = new PhoneApplicationFrame();
            RootFrame.Navigated += CompleteInitializePhoneApplication;
            // Handle navigation failures
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;
            // Ensure we don't initialize again
            phoneApplicationInitialized = true;
        }
        // Do not add any additional code to this method
        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
        {
            // Set the root visual to allow the application to render
            if (RootVisual != RootFrame)
                RootVisual = RootFrame;
            // Remove this handler since it is no longer needed
            RootFrame.Navigated -= CompleteInitializePhoneApplication;
        }
        #endregion
    }
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-65092-1-1.html 上篇帖子: Windows Embedded Compact 7开发环境的搭建 下篇帖子: Windows Phone 7 位图BitmapImage和WriteableBitmap
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表