【WPF.NET】演练:创建触控应用程序

本文内容

  1. 先决条件
  2. 创建应用程序
  3. 测试应用程序

WPF 使应用程序能够响应触控。 例如,可以通过在触控敏感型设备(如触摸屏)上使用一根或多根手指与应用程序交互。本演练创建了一个应用程序,使用户能够使用触控来移动、旋转单个对象或重设其大小。

一、先决条件

你需要满足以下条件才能完成本演练:

  • Visual Studio。

  • 一种接受触控输入的设备,例如支持 Windows Touch 的触摸屏。

此外,应对如何在 WPF 中创建应用程序,尤其是如何订阅和处理事件有一个基本的了解。 

二、创建应用程序

  1. 使用 Visual C# 创建名为 BasicManipulation 的新 WPF 应用程序项目。 

  2. 将 MainWindow.xaml 的内容替换为以下 XAML。

    此标记创建一个简单的应用程序,该应用程序在 Canvas 上包含一个红色 Rectangle。 Rectangle 的 IsManipulationEnabled 属性设置为 true,以便接收操作事件。 应用程序订阅 ManipulationStartingManipulationDelta 和 ManipulationInertiaStarting 事件。 这些事件包含用于在用户操作 Rectangle 时移动它的逻辑。

    XAML复制

    <Window x:Class="BasicManipulation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Move, Size, and Rotate the Square"
            WindowState="Maximized"
            ManipulationStarting="Window_ManipulationStarting"
            ManipulationDelta="Window_ManipulationDelta"
            ManipulationInertiaStarting="Window_InertiaStarting">
      <Window.Resources>
    
        <!--The movement, rotation, and size of the Rectangle is 
            specified by its RenderTransform.-->
        <MatrixTransform x:Key="InitialMatrixTransform">
          <MatrixTransform.Matrix>
            <Matrix OffsetX="200" OffsetY="200"/>
          </MatrixTransform.Matrix>
        </MatrixTransform>
    
      </Window.Resources>
    
      <Canvas>
        <Rectangle Fill="Red" Name="manRect"
                     Width="200" Height="200" 
                     RenderTransform="{StaticResource InitialMatrixTransform}"
                     IsManipulationEnabled="true" />
      </Canvas>
    </Window>
    
    
  3. 在 MainWindow 类中,添加以下 ManipulationStarting 事件处理程序。

    当 WPF 检测到触控输入开始操作对象时,将发生 ManipulationStarting 事件。 代码通过设置 ManipulationContainer 属性来指定操作的位置应相对于 Window

    void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.ManipulationContainer = this;
        e.Handled = true;
    }
    
  4. 在 MainWindow 类中,添加以下 ManipulationDelta 事件处理程序。

    当触控输入改变位置时,会发生 ManipulationDelta 事件,该事件可在操作期间多次发生。 该事件也可以在手指抬起后发生。 例如,如果用户在屏幕上拖动手指,则 ManipulationDelta 事件会在手指移动时发生多次。 当用户从屏幕上抬起手指时,ManipulationDelta 事件会不断发生以模拟惯性。

    该代码将 DeltaManipulation 应用于 Rectangle 的 RenderTransform 以在用户移动触控输入时移动它。 它还会检查当事件在惯性期间发生时,Rectangle 是否超出了 Window 的边界。 如果是,应用程序会调用 ManipulationDeltaEventArgs.Complete 方法来结束操作。

    void Window_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
    
        // Get the Rectangle and its RenderTransform matrix.
        Rectangle rectToMove = e.OriginalSource as Rectangle;
        Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;
    
        // Rotate the Rectangle.
        rectsMatrix.RotateAt(e.DeltaManipulation.Rotation,
                             e.ManipulationOrigin.X,
                             e.ManipulationOrigin.Y);
    
        // Resize the Rectangle.  Keep it square
        // so use only the X value of Scale.
        rectsMatrix.ScaleAt(e.DeltaManipulation.Scale.X,
                            e.DeltaManipulation.Scale.X,
                            e.ManipulationOrigin.X,
                            e.ManipulationOrigin.Y);
    
        // Move the Rectangle.
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y);
    
        // Apply the changes to the Rectangle.
        rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);
    
        Rect containingRect =
            new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
    
        Rect shapeBounds =
            rectToMove.RenderTransform.TransformBounds(
                new Rect(rectToMove.RenderSize));
    
        // Check if the rectangle is completely in the window.
        // If it is not and intertia is occuring, stop the manipulation.
        if (e.IsInertial && !containingRect.Contains(shapeBounds))
        {
            e.Complete();
        }
    
        e.Handled = true;
    }
    
  5. 在 MainWindow 类中,添加以下 ManipulationInertiaStarting 事件处理程序。

    当用户从屏幕上抬起所有手指时,会发生 ManipulationInertiaStarting 事件。 代码设置矩形移动、扩展和旋转的初始速度和减速度。

    void Window_InertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
    {
    
        // Decrease the velocity of the Rectangle's movement by
        // 10 inches per second every second.
        // (10 inches * 96 pixels per inch / 1000ms^2)
        e.TranslationBehavior.DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's resizing by
        // 0.1 inches per second every second.
        // (0.1 inches * 96 pixels per inch / (1000ms^2)
        e.ExpansionBehavior.DesiredDeceleration = 0.1 * 96 / (1000.0 * 1000.0);
    
        // Decrease the velocity of the Rectangle's rotation rate by
        // 2 rotations per second every second.
        // (2 * 360 degrees / (1000ms^2)
        e.RotationBehavior.DesiredDeceleration = 720 / (1000.0 * 1000.0);
    
        e.Handled = true;
    }
    
  6. 生成并运行该项目。

    应会在窗口中看到一个红色方块。

三、测试应用程序

若要测试应用程序,请尝试以下操作。 请注意,可以同时执行以下多项操作。

  • 若要移动 Rectangle,请将手指放在 Rectangle 上,然后在屏幕上移动手指。

  • 若要重设 Rectangle 的大小,请将两根手指放在 Rectangle 上,然后将手指相互靠拢或分开。

  • 若要旋转 Rectangle,请将两根手指放在 Rectangle 上并同向转动手指。

若要引起惯性,请在执行之前的操作时将手指从屏幕上快速抬起。 Rectangle 将继续移动、重设大小或旋转几秒钟,然后才停止。

相关推荐

  1. 【WPF.NET】演练创建应用程序

    2024-01-08 08:38:02       39 阅读
  2. 如何使用 Python 创建 Twitter 应用程序

    2024-01-08 08:38:02       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-08 08:38:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-08 08:38:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-08 08:38:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-08 08:38:02       20 阅读

热门阅读

  1. Nginx常用功能

    2024-01-08 08:38:02       30 阅读
  2. 五、C#与数据库交互( ADO.NET基础)

    2024-01-08 08:38:02       31 阅读
  3. Unity获取相机渲染范围内的所有物体

    2024-01-08 08:38:02       30 阅读
  4. 第一个Flask项目(pycharm社区版)

    2024-01-08 08:38:02       34 阅读
  5. 基于SpringBoot的旅游网站设计

    2024-01-08 08:38:02       39 阅读
  6. 多线程忙循环是什么

    2024-01-08 08:38:02       37 阅读
  7. 数据结构-怀化学院期末题

    2024-01-08 08:38:02       30 阅读
  8. springMVC获取请求参数的方式

    2024-01-08 08:38:02       42 阅读
  9. PyTorch的核心模块介绍

    2024-01-08 08:38:02       35 阅读
  10. C语言基本框架及其含义,C入门

    2024-01-08 08:38:02       36 阅读
  11. js 如何判断对象自身为空?

    2024-01-08 08:38:02       37 阅读