Пошаговое руководство. Создание первого сенсорного приложения
WPF позволяет приложениям реагировать на касание. Например, вы можете взаимодействовать с приложением с помощью одного или нескольких пальцев на сенсорном устройстве, например сенсорный экран, в этом пошаговом руководстве создается приложение, позволяющее пользователю перемещать, изменять размер или повернуть один объект с помощью сенсорного ввода.
Необходимые условия
Для выполнения этого пошагового руководства вам потребуется следующее:
Visual Studio.
Устройство, которое принимает сенсорный ввод, например сенсорный экран, который поддерживает Windows Touch.
Кроме того, вы должны иметь базовое представление о создании приложения в WPF, особенно о том, как подписаться на событие и обрабатывать его. Дополнительные сведения см. в разделе Пошаговое руководство: Мое первое классическое приложение WPF.
Создание приложения
Создание приложения
Создайте проект приложения WPF в Visual Basic или Visual C# с именем
BasicManipulation
. Для получения дополнительной информации см. Пошаговое руководство: Мое первое настольное приложение WPF.Замените содержимое MainWindow.xaml следующим кодом XAML.
Эта разметка создает простое приложение, в котором отображается красный Rectangle на фоне Canvas. Свойство IsManipulationEnabled для Rectangle установлено в значение 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.Событие ManipulationStarting возникает, когда WPF обнаруживает, что сенсорные входные данные начинают управлять объектом. Код указывает, что позиция манипуляции должна быть относительно Window путем задания свойства ManipulationContainer.
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
добавьте следующий обработчик событий ManipulationDelta.Событие ManipulationDelta происходит при изменении положения сенсорного ввода и может происходить несколько раз во время манипуляции. Событие также может возникать после того, как будет поднят палец. Например, если пользователь перетаскивает пальцем по экрану, событие ManipulationDelta происходит несколько раз при перемещении пальца. Когда пользователь поднимает пальцем с экрана, событие ManipulationDelta продолжает происходить для имитации инерции.
Код применяет DeltaManipulation к RenderTransformRectangle для перемещения его вслед за касанием пользователем. Он также проверяет, находится ли 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
добавьте следующий обработчик событий 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; }
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, поместите пальцем на Rectangle и переместите пальцем по экрану.
Чтобы изменить размер Rectangle, поместите два пальца на Rectangle и переместите пальцы ближе друг к другу или дальше друг от друга.
Чтобы повернуть Rectangle, поместите два пальца на Rectangle и поверните пальцы вокруг друг друга.
Чтобы вызвать инерцию, быстро поднять пальцы с экрана при выполнении предыдущих манипуляций. Rectangle будет продолжать перемещаться, изменять размер или поворачиваться в течение нескольких секунд до остановки.
См. также
.NET Desktop feedback