[注意]ファイルを適切な場所に保存後、最初に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 | - | 新規作成 |