[注意]ファイルを適切な場所に保存後、最初にCSSへのパスが適正であるかを確認すること。
[概要を記載します]
Microsoft ホームページで紹介されている「チュートリアル: 初めてのタッチ アプリケーションの作成 - WPF .NET Framework | Microsoft Learn」を実際に作成して動作確認してみます。
※ 私の都合でオリジナルから若干変更しています。
コンパイラ : | Visual Studio 2022 community, | Version 17.10.0 |
フレームワーク : | .NET Framework, | 4.8 |
OS : | Windows11 home, | 23H2 |
1. Visual C# で、BasicManipulation という名前の WPF アプリケーション プロジェクトを作成します。
2. MainWindow.XAML の内容を次の XAML に置き換えます。
このマークアップを使用して、Canvas に赤い Rectangle を含む単純なアプリケーションを作成します。
Rectangle の IsManipulationEnabled プロパティは、操作イベントを受け取るために true
に設定されています。アプリケーションから、ManipulationStarting、ManipulationDelta、および ManipulationInertiaStarting イベントをサブスクライブします。
これらのイベントには、ユーザーの操作時に Rectangle を移動するロジックが含まれています。
["MainWindow.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"
ManipulationStarting="Window_ManipulationStarting"
ManipulationDelta="Window_ManipulationDelta"
ManipulationInertiaStarting="Window_InertiaStarting" Width="800" Height="600">
<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>
NOTE
「IsManupuiationEnable="true"」を指定することで、この Rectangle がタッチ操作の対象であることを設定しています。
3. 次の ManipulationStarting イベント ハンドラーを MainWindow クラスに追加します。
ManipulationStarting イベントは、タッチ入力によりオブジェクトの操作が始まったことが WPF で検出されたときに発生します。 このコードの場合、ManipulationContainer プロパティを設定することで、操作の位置が Window に対して相対的であることを指定しています。
["MainWindow.xaml.cs"]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BasicManipulation { ////// MainWindow.xaml の相互作用ロジック /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { e.ManipulationContainer = this; e.Handled = true; } } }
4. 次の ManipulationDelta イベント ハンドラーを MainWindow クラスに追加します。
ManipulationDelta イベントは、タッチ入力の位置が変わると発生し、1 回の操作中に複数回発生する可能性があります。このイベントは、指を上げた後にも発生する可能性があります。たとえば、ユーザーが画面上で指をドラッグすると、ManipulationDelta イベントは指の移動時に複数回発生します。 ユーザーが画面から指を上げると、慣性をシミュレートするために ManipulationDelta イベントは発生し続けます。
このコードでは、ユーザーがタッチ入力を動かすのに合わせて移動されるように DeltaManipulation が Rectangle の RenderTransform に適用されます。 また、慣性の発生中にこのイベントが発生したときに、Rectangle が Window の境界外にあるかどうかも確認されます。 その場合、アプリケーションから ManipulationDeltaEventArgs.Complete メソッドが呼び出され、操作が終了します。
["MainWindow.xaml.cs"]
・・・ namespace BasicManipulation { ////// MainWindow.xaml の相互作用ロジック /// public partial class MainWindow : Window { ・・・ 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. 次の ManipulationInertiaStarting イベント ハンドラーを MainWindow クラスに追加します。
ManipulationInertiaStarting イベントは、ユーザーが画面からすべての指を上げたときに発生します。このコードにより、四角形の移動、拡大、および回転の初期速度と減速を設定します。
["MainWindow.xaml.cs"]
・・・ namespace BasicManipulation { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { ・・・ 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. プロジェクトをビルドして実行します。ウィンドウに赤い四角形が表示されます。
7. アプリケーションのテスト
アプリケーションをテストするために、次の操作を試します。 次のうち、複数の操作を同時に実行できることに注意してください。
最後に全体コードを以下に示します。
["MainWindow.xaml.cs"]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BasicManipulation { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { e.ManipulationContainer = this; e.Handled = true; } 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; } 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; } } }
本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。
2024-05-23 | - | 新規作成 |