WPF 使应用程序能够响应触控。 例如,可以通过在触控敏感型设备(如触摸屏)上使用一根或多根手指与应用程序交互。本演练创建了一个应用程序,使用户能够使用触控来移动、旋转单个对象或重设其大小。
你需要满足以下条件才能完成本演练:
Visual Studio。
一种接受触控输入的设备,例如支持 Windows Touch 的触摸屏。
此外,应对如何在 WPF 中创建应用程序,尤其是如何订阅和处理事件有一个基本的了解。?
使用 Visual C# 创建名为?BasicManipulation
?的新 WPF 应用程序项目。?
将 MainWindow.xaml 的内容替换为以下 XAML。
此标记创建一个简单的应用程序,该应用程序在?Canvas?上包含一个红色?Rectangle。?Rectangle?的?IsManipulationEnabled?属性设置为 true,以便接收操作事件。 应用程序订阅?ManipulationStarting、ManipulationDelta?和?ManipulationInertiaStarting?事件。 这些事件包含用于在用户操作?Rectangle?时移动它的逻辑。
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"
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>
在?MainWindow
?类中,添加以下?ManipulationStarting?事件处理程序。
当 WPF 检测到触控输入开始操作对象时,将发生?ManipulationStarting?事件。 代码通过设置?ManipulationContainer?属性来指定操作的位置应相对于?Window。
void Window_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
e.ManipulationContainer = this;
e.Handled = true;
}
在?MainWindow
?类中,添加以下?ManipulationDelta?事件处理程序。
当触控输入改变位置时,会发生?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;
}
在?MainWindow
?类中,添加以下?ManipulationInertiaStarting?事件处理程序。
当用户从屏幕上抬起所有手指时,会发生?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;
}
生成并运行该项目。
应会在窗口中看到一个红色方块。
若要测试应用程序,请尝试以下操作。 请注意,可以同时执行以下多项操作。
若要引起惯性,请在执行之前的操作时将手指从屏幕上快速抬起。?Rectangle?将继续移动、重设大小或旋转几秒钟,然后才停止。