Procedura dettagliata: creazione della prima applicazione a tocco
WPF consente alle applicazioni di rispondere al tocco. È ad esempio possibile interagire con un'applicazione utilizzando uno o più dita su un dispositivo sensibile al tocco, ad esempio un touchscreen. In questa procedura dettagliata viene creata un'applicazione che consente all'utente di spostarsi, ridimensionare o ruotare un singolo oggetto tramite tocco.
Prerequisiti
Per completare la procedura dettagliata, è necessario disporre dei componenti seguenti:
Microsoft Visual Studio 2010.
Windows 7.
Un dispositivo in grado di accettare l'input tocco, ad esempio un touchscreen che supporta Windows Touch.
È inoltre necessario disporre di una conoscenza di base della modalità di creazione di un'applicazione in WPF, in particolare della modalità di sottoscrizione e di gestione di un evento. Per ulteriori informazioni, vedere Procedura dettagliata: introduzione a WPF.
Creazione dell'applicazione
Per creare l'applicazione
Creare un nuovo progetto di applicazione WPF in Visual Basic o Visual C# denominato BasicManipulation. Per ulteriori informazioni, vedere Procedura: creare un nuovo progetto di applicazione WPF.
Sostituire il contenuto di MainWindow.xaml con il codice XAML riportato di seguito.
Questo markup consente di creare un'applicazione semplice contenente un oggetto Rectangle di colore rosso su un oggetto Canvas. La proprietà IsManipulationEnabled di Rectangle viene impostata su true in modo che possa ricevere gli eventi di modifica. L'applicazione sottoscrive gli eventi ManipulationStarting, ManipulationDelta e ManipulationInertiaStarting. Questi eventi contengono la logica per spostare Rectangle quando l'utente lo modifica.
<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>
Se si utilizza Visual Basic, nella prima riga di MainWindow.xaml sostituire x:Class="BasicManipulation.MainWindow" con x:Class="MainWindow".
Nella classe MainWindow aggiungere il gestore eventi ManipulationStarting.
L'evento ManipulationStarting si verifica quando WPF rileva l'inizio della modifica di un oggetto tramite input tocco. Nel codice viene specificato che la posizione della modifica deve essere relativa a Window impostando la proprietà ManipulationContainer.
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; }
Nella classe MainWindow aggiungere il gestore eventi ManipulationDelta.
L'evento ManipulationDelta si verifica quando la posizione viene modificata tramite input tocco e può verificarsi più volte durante la modifica. L'evento può inoltre verificarsi dopo il sollevamento di un dito. Ad esempio, se l'utente sposta un dito su uno schermo, l'evento ManipulationDelta si verifica più volte durante lo spostamento del dito. Quando l'utente solleva un dito dallo schermo, l'evento ManipulationDelta continua a verificarsi per simulare l'inerzia.
Nel codice viene applicata la proprietà DeltaManipulation alla proprietà RenderTransform dell'oggetto Rectangle in modo da spostarlo mentre l'utente sposta l'input tocco. Viene inoltre verificato se l'oggetto Rectangle si trova al di fuori dei limiti dell'oggetto Window quando l'evento si verifica durante l'inerzia. In caso affermativo, l'applicazione chiama il metodo ManipulationDeltaEventArgs.Complete per terminare la modifica.
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; }
Nella classe MainWindow aggiungere il gestore eventi ManipulationInertiaStarting.
L'evento ManipulationInertiaStarting si verifica quando l'utente solleva tutte le dita dallo schermo. Nel codice viene impostata la velocità iniziale e la decelerazione per il movimento, l'espansione e la rotazione del rettangolo.
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; }
Compilare ed eseguire il progetto.
Nella finestra verrà visualizzato un quadrato di colore rosso.
Verifica dell'applicazione
Per testare l'applicazione, provare a eseguire le modifiche che seguono. Si noti che è possibile eseguire più modifiche contemporaneamente.
Per spostare Rectangle, posizionare un dito su Rectangle e spostare il dito sullo schermo.
Per ridimensionare Rectangle, posizionare due dita su Rectangle e aprire o chiudere le dita.
Per ruotare Rectangle, posizionare due dita su Rectangle e ruotare un dito intorno all'altro.
Per causa l'inerzia, sollevare velocemente le dita dallo schermo durante l'esecuzione delle modifiche precedenti. L'oggetto Rectangle continuerà a venire spostato, ridimensionato o ruotato per qualche secondo prima che si fermi.