逐步解說:建立您的第一個觸控應用程式

WPF 可讓應用程式回應觸控。 例如,您可以在觸控式裝置上使用一或多個手指與應用程式互動,例如觸控螢幕 本逐步解說會建立一個應用程式,讓使用者使用觸控移動、調整大小或旋轉單一物件。

必要條件

您需要下列元件才能完成這個逐步解說:

  • Visual Studio。

  • 接受觸控輸入的裝置,例如支援 Windows Touch 的觸控螢幕。

此外,您應該對如何在 WPF 中建立應用程式有基本瞭解,特別是如何訂閱及處理事件。 如需詳細資訊,請參閱逐步解說︰我的第一個 WPF 桌面應用程式

建立應用程式

若要建立應用程式

  1. 在 Visual Basic 或 Visual C# 中,建立名為 BasicManipulation 的新 WPF 應用程式專案。 如需詳細資訊,請參閱逐步解說︰我的第一個 WPF 桌面應用程式

  2. 以下列 XAML 取代 MainWindow.xaml 的內容。

    此標記會建立簡單的應用程式,其中包含 上的 Canvas 紅色 Rectangle 。 的 IsManipulationEnabledRectangle 屬性設定為 true,以便接收操作事件。 應用程式會 ManipulationStarting 訂閱 、 ManipulationDeltaManipulationInertiaStarting 事件。 這些事件包含當使用者操作時移動 的 Rectangle 邏輯。

    <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. 如果您使用 Visual Basic,請在 MainWindow.xaml 的第一行中,將 取代 x:Class="BasicManipulation.MainWindow"x:Class="MainWindow"

  4. 在 類別中 MainWindow ,新增下列 ManipulationStarting 事件處理常式。

    ManipulationStarting當 WPF 偵測到觸控輸入開始操作物件時,就會發生此事件。 程式碼會藉由設定 ManipulationContainer 屬性,指定操作的位置應該相對於 Window

    void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.ManipulationContainer = this;
        e.Handled = true;
    }
    
    Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs)
        e.ManipulationContainer = Me
        e.Handled = True
    End Sub
    
  5. 在 類別中 MainWindow ,新增下列 ManipulationDelta 事件處理常式。

    ManipulationDelta 觸控輸入變更位置,而且可以在操作期間多次發生時,就會發生此事件。 引發手指之後,也可能會發生此事件。 例如,如果使用者將手指拖曳到螢幕上,就會 ManipulationDelta 在手指移動時多次發生此事件。 當使用者從螢幕舉起手指時,事件 ManipulationDelta 會持續發生以模擬慣性。

    程式碼會將 DeltaManipulation 套用至 RenderTransformRectangle ,以在使用者移動觸控輸入時移動它。 它也會檢查 是否 RectangleWindow 慣性期間發生事件時超出 界限。 如果是,應用程式會呼叫 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;
    }
    
    Private Sub Window_ManipulationDelta(ByVal sender As Object, ByVal e As ManipulationDeltaEventArgs)
    
        ' Get the Rectangle and its RenderTransform matrix.
        Dim rectToMove As Rectangle = e.OriginalSource
        Dim rectTransform As MatrixTransform = rectToMove.RenderTransform
        Dim rectsMatrix As Matrix = rectTransform.Matrix
    
    
        ' Rotate the shape
        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 center
        rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                              e.DeltaManipulation.Translation.Y)
    
        ' Apply the changes to the Rectangle.
        rectTransform = New MatrixTransform(rectsMatrix)
        rectToMove.RenderTransform = rectTransform
    
        Dim container As FrameworkElement = e.ManipulationContainer
        Dim containingRect As New Rect(container.RenderSize)
    
        Dim shapeBounds As Rect = rectTransform.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 AndAlso Not containingRect.Contains(shapeBounds) Then
            e.Complete()
        End If
    
        e.Handled = True
    End Sub
    
  6. 在 類別中 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;
    }
    
    Private Sub Window_InertiaStarting(ByVal sender As Object,
                                       ByVal e As ManipulationInertiaStartingEventArgs)
    
        ' 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
    End Sub
    
  7. 建置並執行專案。

    您應該會在視窗中看到紅色方塊。

測試應用程式

若要測試應用程式,請嘗試下列操作。 請注意,您可以同時執行下列其中一項以上作業。

  • 若要移動 Rectangle ,請將手指放在 上 Rectangle ,並在螢幕上移動手指。

  • 若要調整大小 Rectangle ,請將兩根手指放在 上 Rectangle ,並將手指更接近或彼此分開。

  • 若要旋轉 Rectangle ,請將兩根手指放在 上 Rectangle ,並互相旋轉手指。

若要造成慣性,請在您執行先前的操作時,從螢幕快速抬起手指。 會 Rectangle 繼續移動、調整大小或旋轉幾秒鐘,再停止。

另請參閱