逐步解說:建立您的第一個觸控應用程式
WPF 使應用程式能夠回應觸控。 例如,您可以在觸控式裝置上使用一或多個手指與應用程式互動,例如觸控螢幕 本逐步解說會建立一個應用程式,讓使用者使用觸控移動、重設大小或旋轉單一物件。
必要條件
您需要下列元件才能完成這個逐步解說:
Visual Studio。
支援觸控輸入的裝置,例如支援 Windows Touch 的觸控螢幕。
此外,您應該對如何在 WPF 中建立應用程式有基本的了解,特別是如何訂閱和處理事件。 如需詳細資訊,請參閱逐步解說︰我的第一個 WPF 桌面應用程式。
建立應用程式
若要建立應用程式
在 Visual Basic 或 Visual C# 中,建立名為
BasicManipulation
的新 WPF 應用程式專案。 如需詳細資訊,請參閱逐步解說︰我的第一個 WPF 桌面應用程式。將 MainWindow.xaml 的內容替換為以下 XAML。
此標記會建立一個簡單的應用程式,在 Canvas 上包含一個紅色的 Rectangle。 將 Rectangle 的 IsManipulationEnabled 屬性會設定為 true,以便接收操作事件。 應用程式會訂閱 ManipulationStarting、 ManipulationDelta和 ManipulationInertiaStarting 事件。 這些事件包含當使用者操作時移動 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>
如果您使用 Visual Basic,請在 MainWindow.xaml 的第一行中,將
x:Class="BasicManipulation.MainWindow"
取代為x:Class="MainWindow"
。在
MainWindow
類別中,添加以下 ManipulationStarting 事件處理程式。當 WPF 偵測到觸控輸入開始操作物件時,會觸發 ManipulationStarting 事件。 此程式碼透過設定 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
在
MainWindow
類別中,添加以下 ManipulationStarting 事件處理程式。當觸控輸入位置變更時,會觸發 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; }
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
在
MainWindow
類別中,添加以下 ManipulationStarting 事件處理程式。當使用者將所有手指從螢幕上抬起時,會觸發 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
建置並執行專案。
您應該會看到一個紅色方塊出現在視窗中。
測試應用程式
若要測試應用程式,請嘗試以下操作。 請注意,您可以同時進行以下多項操作。
若要引發慣性,請在執行前述操作時迅速將手指從螢幕上抬起。 該 Rectangle 會繼續移動、調整大小或旋轉幾秒鐘,然後停止。