연습: 첫 번째 터치 애플리케이션 만들기
WPF를 사용하면 애플리케이션이 터치에 응답할 수 있습니다. 예를 들어 터치 스크린과 같은 터치 감지 디바이스에서 하나 이상의 손가락을 사용하여 애플리케이션과 상호 작용할 수 있습니다. 이 연습에서는 터치를 사용하여 단일 개체를 이동, 크기 조정 또는 회전할 수 있는 애플리케이션을 만듭니다.
필수 구성 요소
이 연습을 완료하려면 다음과 같은 구성 요소가 필요합니다.
Visual Studio.
Windows Touch를 지원하는 터치 스크린과 같은 터치 입력을 허용하는 디바이스.
또한 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="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가 터치 입력이 개체를 조작하기 시작하는 것을 감지할 때 발생합니다. 이 코드는 ManipulationContainer 속성을 설정하여 조작 위치에 대해 Window를 기준으로 지정합니다.
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 이벤트가 계속 발생합니다.
이 코드는 사용자가 터치 입력을 이동할 때 이동하도록 Rectangle의 RenderTransform에 DeltaManipulation을 적용합니다. 또한 관성 중에 이벤트가 발생할 때 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은 중지되기 전에 몇 초 동안 계속 이동, 크기 조정 또는 회전합니다.
참고 항목
.NET Desktop feedback