연습: 첫 응용 프로그램 만들기
WPF를 사용하여 응용 프로그램이 터치에 응답할 수 있습니다. 예를 들어 터치 스크린과 같은 터치 인식 장치에서 손가락을 사용하여 응용 프로그램과 상호 작용할 수 있습니다. 이 연습에서는 터치를 통해 단일 개체를 이동, 크기 조정 또는 회전할 수 있는 응용 프로그램을 만듭니다.
사전 요구 사항
이 연습을 완료하려면 다음 구성 요소가 필요합니다.
Microsoft Visual Studio 2010.
Windows 7
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="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://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에 상대적이 되도록 지정합니다.
Private Sub Window_ManipulationStarting(ByVal sender As Object, ByVal e As ManipulationStartingEventArgs) e.ManipulationContainer = Me e.Handled = True End Sub
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 메서드를 호출하여 조작을 종료합니다.
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
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 이벤트는 화면에서 손가락을 모두 치우면 발생합니다. 이 코드에서는 사각형의 이동, 확장 및 회전에 대한 초기 속도와 선언을 설정합니다.
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
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이 2초 동안 계속 이동, 크기 조정 또는 회전하다가 멈춥니다.