zoukankan      html  css  js  c++  java
  • WPF进阶技巧和实战09-事件(2-多点触控)

    多点触控输入

    多点触控输入和传统的基于比的输入的区别是多点触控识别手势,用户可以移动多根手指以执行常见的操作,放大,旋转,拖动等。

    多点触控的输入层次

    WPF允许使用键盘和鼠标的高层次输入(例如单击和文本改变)和低层次输入(鼠标事件和按键事件)。多点触控输入同样应用了这种多层次的输入方式,WPF提供了3个独立的层次:

    • 原始触控(raw touch):这是最低级的支持,可访问用户执行的每个触控。缺点是由应用程序负责将单独的触控消息组合在一起,并对他们进行解释。如果不准备识别标准触摸手势,反而希望创建以独特方式响应多点触控输入的应用程序,使用原始触控是合理的。一个例子就是绘图程序,允许用户同时使用多根手指在触摸屏上绘图。
    • 操作(manipulation):这是一个简便的抽象层,该层将原始的多点触控输入转换成更有意义的手势,与WPF控件将一系列MouseDown和MouseUp事件解释为更高级的MouseDoubleClick事件相似。WPF支持的通用手势包括移动Pan,缩放Zoom,旋转Rotate,轻按Tap
    • 内置的元素支持:有些元素已经对多点触控事件提供了内置的支持,从而不需要在编写代码。例如,可滚动的控件支持触控移动,ListBox、ListView、DataGrid、TextBox、ScrollViewer

    原始触控

    触控事件被内置到了低级的UIElement以及ContentElemnet类。所有元素的原始触控事件:

    名称 路由类型 说明
    PreviewTouchDown 隧道 当用户触摸元素时发生
    TouchDown 冒泡 当用户触摸元素时发生
    PreviewTouchMove 隧道 当用户移动放到触摸屏上的手指时发生
    TouchMove 冒泡 当用户移动放到触摸屏上的手指时发生
    PreviewTouchUp 隧道 当用户移开手指,结束触摸时发生
    TouchUp 冒泡 当用户移开手指,结束触摸时发生
    TouchEnter 当触点从元素外进入元素内时发生
    TouchLeave 当触点离开元素时发生

    所有这些事件都提供了一个TouchEventArgs对象,该对象提供了两个重要成员。第一个是GetTouchPoint()方法,该方法返回触控事件发生位置的屏幕坐标(还有触点的大小等)。第二个是TouchDevice属性,该属性返回一个TouchDevice对象。这里的技巧是将每个触点视为单独设备。因此,如果用户在不同的位置按下两根手指(同时按下或者先按下一个再按下一个),WPF将他们作为两个触控设备,并为每个触控设备指定唯一的ID,当用户移动这些手指,并且触控事件发生时,代码可以通过TouchDevice.ID属性区分两个触点。

    操作

    WPF为手势提供了更高级的支持,称为触控操作。通过将元素的IsManipulationEnabled属性设置为true,使元素接受触控操作。然后可响应4个操作事件:

    ManipulationStarting、ManipulationStarted、ManipulationDelta、ManipulationComplted。

    <Window x:Class="Multitouch.Manipulations"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Manipulations" Height="349" Width="607">
        
        <Grid>
            <Canvas x:Name="canvas" ManipulationStarting="image_ManipulationStarting"  ManipulationDelta="image_ManipulationDelta">
                <Image Canvas.Top="10" Canvas.Left="10" Width="200" IsManipulationEnabled="True" Source="koala.jpg">
                    <Image.RenderTransform>
                        <MatrixTransform></MatrixTransform>
                    </Image.RenderTransform>
                </Image>
                <Image Canvas.Top="30" Canvas.Left="350" Width="200" IsManipulationEnabled="True" Source="penguins.jpg">
                    <Image.RenderTransform>
                        <MatrixTransform></MatrixTransform>
                    </Image.RenderTransform>
                </Image>
                <Image Canvas.Top="100" Canvas.Left="200" Width="200" IsManipulationEnabled="True" Source="tulips.jpg">
                    <Image.RenderTransform>
                        <MatrixTransform></MatrixTransform>
                    </Image.RenderTransform>
                </Image>
            </Canvas>
        </Grid>
    </Window>
    
    public partial class Manipulations : Window
        {
            public Manipulations()
            {
                InitializeComponent();
            }
    
            private void image_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
            {
                // Set the container (used for coordinates.)
                e.ManipulationContainer = canvas;
    
                // Choose what manipulations to allow.
                e.Mode = ManipulationModes.All;
            }
    
            private void image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
            {
                // Get the image that's being manipulated.            
                FrameworkElement element = (FrameworkElement)e.Source;
    
                // Use the matrix to manipulate the element.
                Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;
    
                var deltaManipulation = e.DeltaManipulation;
                // Find the old center, and apply the old manipulations.
                Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);
                center = matrix.Transform(center);
    
                // Apply zoom manipulations.
                matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);
    
                // Apply rotation manipulations.
                matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);
    
                // Apply panning.
                matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
    
                // Set the final matrix.
                ((MatrixTransform)element.RenderTransform).Matrix = matrix;
    
            }
        }
    

    上面每个图像都包含一个MatrixTransform对象,该对象为代码应用移动、旋转、缩放等操作的组合提供了一个简易方式。当操作发生时,将使用代码改变他们。
    当触摸一幅图时,将触发ManipulationStarting事件。这时,设置操作容器(后面将获得所有操作坐标的参考点)。当操作发生时,触发ManipulationDelta事件,例如用户开始旋转一幅图像,将不断触发这个事件,直到用户旋转停止或者抬起手指为止。

    通过使用ManipulationDelta对象将手势的当前状态记录下来,该对象是通过ManipulationDeltaEventArgs.DeltaManipulation属性提供的。本质上,ManipulationDelta对象记录了应该应用到对象的缩放、旋转、移动的量,分别有3个简单的属性提供,Scale、Rotation、Translation,通过这3个数据来调整用户界面的元素。

    惯性

    本质上,通过惯性可以更逼真的更流畅的操作元素。如上例中,当手指从触摸屏抬起时图像会立即停止一定。但如果启用了惯性特性,那么图像会继续移动非常短的一段时间,正常地减速。将元素拖动进他们不能穿过的边界时,惯性还会使元素弹回来。

    添加惯性特性,只需处理ManipulationInertiaStarting事件。该事件从一幅图像开始并冒泡到Canvas面板。当用户结束手势并抬起手指释放元素时,触发该事件。可使用ManipulationInertiaStartingEventArgs对象确定当前速度,并设置希望的减速度。

  • 相关阅读:
    how to install VLC Player on Fedora 32 Workstation
    Centos 8.2 2004镜像地址
    Fedora 33 Workstation: x86_64 DVD ISO
    [听力/口语]每天十分鐘回音練習
    CSS设置背景色
    设置禁止子标签超出父标签产生了滚动条
    引用自定义的css或者js文件
    js 中使用typeof
    React native 之 Promise
    Mac升级系统后 Pod Install报错-不能用 解决办法
  • 原文地址:https://www.cnblogs.com/vigorous/p/15541930.html
Copyright © 2011-2022 走看看