逐步解說:建立您的第一個觸控應用程式Walkthrough: Creating Your First Touch Application

WPFWPF 讓應用程式回應觸控。enables applications to respond to touch. 比方說,您可以使用其中一個互動應用程式或更多根手指觸控感應裝置,例如本逐步解說中建立的應用程式,可讓使用者移動觸控螢幕上調整大小,或使用觸控旋轉單一物件。For example, you can interact with an application by using one or more fingers on a touch-sensitive device, such as a touchscreen This walkthrough creates an application that enables the user to move, resize, or rotate a single object by using touch.

必要條件Prerequisites

您需要下列元件才能完成此逐步解說:You need the following components to complete this walkthrough:

  • Visual Studio。Visual Studio.

  • 接受輸入,例如觸控螢幕,可支援 Windows Touch 的觸控裝置。A device that accepts touch input, such as a touchscreen, that supports Windows Touch.

此外,您應該有基本的了解如何建立應用程式中的WPFWPF,尤其是如何訂閱和處理事件。Additionally, you should have a basic understanding of how to create an application in WPFWPF, especially how to subscribe to and handle an event. 如需詳細資訊,請參閱逐步解說:我第一個 WPF 桌面應用程式For more information, see Walkthrough: My first WPF desktop application.

建立應用程式Creating the Application

若要建立應用程式To create the application

  1. 在 Visual Basic 或 Visual C# 中,建立名為 BasicManipulation 的新 WPF 應用程式專案。Create a new WPF Application project in Visual Basic or Visual C# named BasicManipulation. 如需詳細資訊,請參閱逐步解說:我第一個 WPF 桌面應用程式For more information, see Walkthrough: My first WPF desktop application.

  2. MainWindow.xaml 的內容取代為下列 XAML。Replace the contents of MainWindow.xaml with the following XAML.

    此標記會建立簡單的應用程式,其中包含紅色RectangleCanvasThis markup creates a simple application that contains a red Rectangle on a Canvas. IsManipulationEnabled屬性Rectangle設為 true,因此它會接收操作事件。The IsManipulationEnabled property of the Rectangle is set to true so that it will receive manipulation events. 應用程式訂閱ManipulationStartingManipulationDelta,和ManipulationInertiaStarting事件。The application subscribes to the ManipulationStarting, ManipulationDelta, and ManipulationInertiaStarting events. 這些事件包含邏輯來移動Rectangle使用者時操作它。These events contain the logic to move the Rectangle when the user manipulates it.

    <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"If you are using Visual Basic, in the first line of MainWindow.xaml, replace x:Class="BasicManipulation.MainWindow" with x:Class="MainWindow".

  4. MainWindow類別中,新增下列ManipulationStarting事件處理常式。In the MainWindow class, add the following ManipulationStarting event handler.

    ManipulationStarting就會發生事件時WPFWPF偵測到該觸控輸入開始操作的物件。The ManipulationStarting event occurs when WPFWPF detects that touch input begins to manipulate an object. 程式碼會指定操作位置應該是相對於Window藉由設定ManipulationContainer屬性。The code specifies that the position of the manipulation should be relative to the Window by setting the ManipulationContainer property.

    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事件處理常式。In the MainWindow class, add the following ManipulationDelta event handler.

    ManipulationDelta觸控輸入變更位置,並可於操作期間發生多次時,就會發生事件。The ManipulationDelta event occurs when the touch input changes position and can occur multiple times during a manipulation. 手指引發之後,也會發生此事件。The event can also occur after a finger is raised. 例如,如果使用者的螢幕上拖曳手指ManipulationDelta手指移事件會發生一次。For example, if the user drags a finger across a screen, the ManipulationDelta event occurs multiple times as the finger moves. 當使用者引發從畫面中,手指ManipulationDelta事件持續發生,模擬慣性。When the user raises a finger from the screen, the ManipulationDelta event keeps occurring to simulate inertia.

    程式碼會套用DeltaManipulationRenderTransformRectangle移動它,當使用者移動觸控輸入。The code applies the DeltaManipulation to the RenderTransform of the Rectangle to move it as the user moves the touch input. 它也會檢查是否Rectangle超出範圍Window在慣性期間的事件發生時。It also checks whether the Rectangle is outside the bounds of the Window when the event occurs during inertia. 因此,應用程式呼叫如果ManipulationDeltaEventArgs.Complete方法以結束操作。If so, the application calls the ManipulationDeltaEventArgs.Complete method to end the manipulation.

    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事件處理常式。In the MainWindow class, add the following ManipulationInertiaStarting event handler.

    ManipulationInertiaStarting事件發生於使用者引發從畫面的所有根手指。The ManipulationInertiaStarting event occurs when the user raises all fingers from the screen. 程式碼設定的初始速度和移動、 擴充和旋轉該矩形的減速。The code sets the initial velocity and deceleration for the movement, expansion, and rotation of the rectangle.

    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. 建置並執行專案。Build and run the project.

    您應該會看到視窗中顯示為紅色方形。You should see a red square appear in the window.

測試應用程式Testing the Application

若要測試應用程式,請嘗試下列操作。To test the application, try the following manipulations. 請注意,您可以多個下列其中之一在相同的時間。Note that you can do more than one of the following at the same time.

  • 若要移動Rectangle,將手指放Rectangle並將手指移動螢幕上。To move the Rectangle, put a finger on the Rectangle and move the finger across the screen.

  • 若要調整大小Rectangle,將兩隻手指放在Rectangle,然後將手指,更接近手指或分開彼此。To resize the Rectangle, put two fingers on the Rectangle and move the fingers closer together or farther apart from each other.

  • 若要旋轉Rectangle,將兩隻手指放在Rectangle並旋轉手指。To rotate the Rectangle, put two fingers on the Rectangle and rotate the fingers around each other.

若要使慣性,快速將引發手指已離開螢幕當您執行先前的操作。To cause inertia, quickly raise your fingers from the screen as you perform the previous manipulations. Rectangle會繼續移動、 調整大小或旋轉幾秒鐘的時間之前就會停止。The Rectangle will continue to move, resize, or rotate for a few seconds before it stops.

另請參閱See also