チュートリアル: 初めてのタッチ アプリケーションの作成
WPF では、タッチに応答するアプリケーションを作成できます。 たとえば、タッチスクリーンなどのタッチを検知するデバイスで 1 本または複数本の指を使用してアプリケーションを操作できます。このチュートリアルでは、タッチすることで単一のオブジェクトを移動、サイズ変更または回転させることのできるアプリケーションを作成します。
前提条件
このチュートリアルを実行するには、次のコンポーネントが必要です。
Microsoft Visual Studio 2010.
Windows 7。
Windows タッチをサポートする、タッチスクリーンなどのタッチ入力ができるデバイス。
また、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="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://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 イベント ハンドラーを追加します。
ManipulationStarting イベントは、WPF がタッチ入力によるオブジェクト操作の開始を検知すると発生します。 コードでは、ManipulationContainer プロパティを設定することで、操作の位置が Window と相対するように指定します。
Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs) e.ManipulationContainer = Me e.Handled = True End Sub
void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { e.ManipulationContainer = this; e.Handled = true; }
MainWindow クラスに、次の ManipulationDelta イベント ハンドラーを追加します。
ManipulationDelta イベントは、タッチ入力の位置が変更されると発生し、一度の操作中に複数回発生することがあります。 イベントは、指を離した後にも発生します。 たとえば、ユーザーが画面上で指をドラッグすると、ManipulationDelta イベントは指が移動するたびに複数回発生します。 ユーザーが指を画面から離すと、ManipulationDelta イベントは慣性をシミュレートするために発生し続けます。
コードでは、ユーザーのタッチ入力に沿って移動するために、Rectangle の RenderTransform に DeltaManipulation を適用します。 また、慣性処理中にイベントが発生したときに、Rectangle が Window の境界の外側にあるかどうかもチェックします。 境界の外側にある場合、アプリケーションは ManipulationDeltaEventArgs.Complete メソッドを呼び出して操作を終了します。
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
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; }
MainWindow クラスに、次の ManipulationInertiaStarting イベント ハンドラーを追加します。
ユーザーが画面からすべての指を離すと、ManipulationInertiaStarting イベントが発生します。 コードにより、四角形の移動、拡大および回転に対する初期の速度と減速度が設定されます。
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
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; }
プロジェクトをビルドして実行します。
ウィンドウ内に赤い正方形が表示されます。
アプリケーションのテスト
アプリケーションをテストするには、次の操作を試します。 一度に複数の操作を試すことができます。
慣性を発生させるには、直前の操作を実行したときに画面からすばやく指を離します。 Rectangle は、停止するまでの数秒間、移動、サイズ変更または回転を続けます。