Cenni preliminari sulle trasformazioni
In questo argomento viene descritto come utilizzare le classi Transform 2-D per ruotare, ridimensionare, spostare (traslare) e inclinare oggetti FrameworkElement.
Nel presente argomento sono contenute le seguenti sezioni.
- Definizione di trasformazione
- Classi Transform
- Proprietà di trasformazione comuni
- Trasformazioni e sistemi di coordinate
- Trasformazione di FrameworkElement
- Esempio: rotazione di un oggetto FrameworkElement di 45 gradi
- Animazione delle trasformazioni
- Funzionalità dell'oggetto Freezable
- Argomenti correlati
Definizione di trasformazione
Un oggetto Transform definisce come eseguire il mapping dei punti, ovvero trasformare i punti, da uno spazio di coordinate a un altro spazio di coordinate. Questo mapping è descritto da un oggetto Matrix di trasformazione, che è un insieme di tre righe con tre colonne di valori Double.
Nota |
---|
In Windows Presentation Foundation (WPF) vengono utilizzate matrici ordinate in base alla riga.I vettori sono espressi come vettori di riga anziché come vettori di colonna. |
Nella tabella seguente viene illustrata la struttura di una matrice WPF.
Matrice di trasformazione 2D
Valore predefinito: 1,0 |
Valore predefinito: 0,0 |
0.0 |
Valore predefinito: 0,0 |
Valore predefinito: 1,0 |
0.0 |
Valore predefinito: 0,0 |
Valore predefinito: 0,0 |
1.0 |
Modificando i valori della matrice, è possibile ruotare, ridimensionare, inclinare e spostare (traslare) un oggetto. Ad esempio, se si modifica il valore nella prima colonna della terza riga (il valore OffsetX) in 100, è possibile utilizzarlo per spostare un oggetto di 100 unità lungo l'asse x. Se si imposta il valore nella seconda colonna della seconda riga su 3, è possibile utilizzarlo per allungare un oggetto fino a un'altezza tre volte superiore a quella corrente. Se si modificano entrambi i valori, si sposta l'oggetto di 100 unità lungo l'asse x e se ne aumenta l'altezza di un fattore di 3. Poiché in Windows Presentation Foundation (WPF) vengono supportate solo le trasformazioni affini, i valori nella colonna di destra sono sempre 0, 0, 1.
Anche se in Windows Presentation Foundation (WPF) è possibile modificare direttamente i valori della matrice, vengono comunque fornite diverse classi Transform che permettono di trasformare un oggetto senza conoscere la configurazione della struttura della matrice sottostante. Ad esempio, la classe ScaleTransform consente di ridimensionare un oggetto impostando le relative proprietà ScaleX e ScaleY, anziché modificando una matrice di trasformazione. Analogamente, la classe RotateTransform consente di ruotare un oggetto impostando semplicemente la relativa proprietà Angle.
Classi Transform
In Windows Presentation Foundation (WPF) sono disponibili le seguenti classi Transform 2-D per le comuni operazioni di trasformazione:
Classe |
Descrizione |
Esempio |
Illustrazione |
---|---|---|---|
Ruota un elemento in base al valore Angle specificato. |
|||
Ridimensiona un elemento in base ai valori ScaleX e ScaleY specificati. |
|||
Inclina un elemento in base ai valori AngleX e AngleY specificati. |
|||
Sposta (trasla) un elemento in base ai valori X e Y specificati. |
Per la creazione di trasformazioni più complesse, in Windows Presentation Foundation (WPF) sono disponibili le due classi seguenti:
Classe |
Descrizione |
Esempio |
---|---|---|
Raggruppa più oggetti TransformGroup in un unico oggetto Transform che è quindi possibile applicare alle proprietà di trasformazione. |
||
Crea trasformazioni personalizzate che non sono fornite dalle altre classi Transform. Quando si utilizza MatrixTransform, si modifica direttamente una matrice. |
Procedura: utilizzare un MatrixTransform per creare trasformazioni personalizzate |
In Windows Presentation Foundation (WPF) sono inoltre disponibili le trasformazioni 3-D. Per ulteriori informazioni, vedere la classe Transform3D.
Proprietà di trasformazione comuni
Per trasformare un oggetto, è possibile dichiarare il tipo Transform appropriato e applicarlo alla proprietà di trasformazione dell'oggetto. Tipi diversi di oggetti hanno tipi diversi di proprietà di trasformazione. Nella tabella seguente sono elencati alcuni tipi Windows Presentation Foundation (WPF) comunemente utilizzati e le relative proprietà di trasformazione.
Tipo |
Proprietà di trasformazione |
---|---|
Trasformazioni e sistemi di coordinate
Quando si trasforma un oggetto, non si trasforma solo l'oggetto, ma anche lo spazio di coordinate in cui esiste. Per impostazione predefinita, una trasformazione è allineata al centro in corrispondenza dell'origine del sistema di coordinate dell'oggetto di destinazione: (0,0). L'unica eccezione è TranslateTransform, per cui non sono disponibili proprietà di allineamento al centro da impostare, perché l'effetto di traslazione è identico indipendentemente dal punto in cui avviene l'allineamento al centro.
Nell'esempio seguente viene utilizzato un oggetto RotateTransform per ruotare un elemento Rectangle (un tipo di FrameworkElement) di 45 gradi rispetto al centro predefinito (0,0) dell'elemento. Nell'immagine seguente viene illustrato l'effetto della rotazione.
Elemento Rectangle ruotato di 45 gradi intorno al punto (0,0)
<Canvas Width="200" Height="200">
<Rectangle
Canvas.Left="100" Canvas.Top="100"
Width="50" Height="50"
Fill="RoyalBlue" Opacity="1.0">
<Rectangle.RenderTransform>
<RotateTransform Angle="45" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Per impostazione predefinita, l'elemento ruota intorno al relativo angolo superiore sinistro, (0, 0). Le classi RotateTransform, ScaleTransform e SkewTransform forniscono le proprietà CenterX e CenterY che consentono di specificare il punto in cui viene applicata la trasformazione.
Anche nell'esempio riportato di seguito viene utilizzato un oggetto RotateTransform per ruotare di 45 gradi un elemento Rectangle, ma in questo caso le proprietà CenterX e CenterY sono impostate in modo che il centro di RotateTransform corrisponda a (25, 25). Nell'immagine seguente viene illustrato l'effetto della rotazione.
Elemento Rectangle ruotato di 45 gradi intorno al punto (25,25)
<Canvas Width="200" Height="200">
<Rectangle
Canvas.Left="100" Canvas.Top="100"
Width="50" Height="50"
Fill="RoyalBlue" Opacity="1.0">
<Rectangle.RenderTransform>
<RotateTransform Angle="45" CenterX="25" CenterY="25" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Trasformazione di FrameworkElement
Per applicare le trasformazioni a FrameworkElement, creare un oggetto Transform e applicarlo a una delle due proprietà rese disponibili dalla classe FrameworkElement:
LayoutTransform: una trasformazione applicata prima del passaggio di layout. Dopo l'applicazione della trasformazione, il sistema di layout elabora le dimensioni e la posizione trasformate dell'elemento.
RenderTransform: una trasformazione che modifica l'aspetto dell'elemento ma viene applicata dopo il completamento del passaggio di layout. Utilizzando la proprietà RenderTransform anziché la proprietà LayoutTransform, è possibile ottenere vantaggi nelle prestazioni.
Quale proprietà utilizzare? Poiché offre vantaggi nelle prestazioni, utilizzare la proprietà RenderTransform laddove possibile, soprattutto quando si utilizzano oggetti Transform animati. Utilizzare la proprietà LayoutTransform quando si ridimensiona, ruota o inclina un elemento ed è necessario adattare il relativo elemento padre alle dimensioni trasformate. Notare che, quando vengono utilizzati con la proprietà LayoutTransform, gli oggetti TranslateTransform sembrano non avere effetto sugli elementi. Ciò è dovuto al fatto che il sistema di layout riporta l'elemento traslato nella posizione originale come parte dell'elaborazione.
Per ulteriori informazioni sul layout in Windows Presentation Foundation (WPF), vedere Sistema di layout.
Esempio: rotazione di un oggetto FrameworkElement di 45 gradi
Nell'esempio seguente viene utilizzato un oggetto RotateTransform per ruotare un pulsante di 45 gradi in senso orario. Il pulsante è contenuto in un oggetto StackPanel che include altri due pulsanti.
Per impostazione predefinita, RotateTransform ruota intorno al punto (0, 0). Poiché nell'esempio non viene specificato un valore relativo al centro, il pulsante ruota intorno al punto (0, 0), che corrisponde all'angolo superiore sinistro. RotateTransform viene applicato alla proprietà RenderTransform. Nell'immagine seguente è illustrato il risultato della trasformazione.
Rotazione di 45 gradi in senso orario rispetto all'angolo superiore sinistro
<Border Margin="30"
HorizontalAlignment="Left" VerticalAlignment="Top"
BorderBrush="Black" BorderThickness="1" >
<StackPanel Orientation="Vertical">
<Button Content="A Button" Opacity="1" />
<Button Content="Rotated Button">
<Button.RenderTransform>
<RotateTransform Angle="45" />
</Button.RenderTransform>
</Button>
<Button Content="A Button" Opacity="1" />
</StackPanel>
</Border>
Anche nell'esempio riportato di seguito viene utilizzato un oggetto RotateTransform per ruotare un pulsante di 45 gradi in senso orario, ma viene inoltre impostata la proprietà RenderTransformOrigin del pulsante su (0,5, 0,5). Il valore della proprietà RenderTransformOrigin è relativo alle dimensioni del pulsante. Di conseguenza, la rotazione viene applicata al centro del pulsante anziché nell'angolo superiore sinistro. Nell'immagine seguente è illustrato il risultato della trasformazione.
Rotazione di 45 gradi in senso orario intorno al centro
<Border Margin="30"
HorizontalAlignment="Left" VerticalAlignment="Top"
BorderBrush="Black" BorderThickness="1">
<StackPanel Orientation="Vertical">
<Button Content="A Button" Opacity="1" />
<Button Content="Rotated Button"
RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<RotateTransform Angle="45" />
</Button.RenderTransform>
</Button>
<Button Content="A Button" Opacity="1" />
</StackPanel>
</Border>
Nell'esempio seguente viene utilizzata la proprietà LayoutTransform anziché la proprietà RenderTransform per ruotare il pulsante. In questo caso la trasformazione influisce sul layout del pulsante e provoca l'attivazione di un passaggio completo da parte del sistema di layout. Di conseguenza, il pulsante viene ruotato e quindi riposizionato perché le relative dimensioni sono state modificate. Nell'immagine seguente è illustrato il risultato della trasformazione.
Utilizzo di LayoutTransform per ruotare il pulsante
<Border Margin="30"
HorizontalAlignment="Left" VerticalAlignment="Top"
BorderBrush="Black" BorderThickness="1">
<StackPanel Orientation="Vertical">
<Button Content="A Button" Opacity="1" />
<Button Content="Rotated Button">
<Button.LayoutTransform>
<RotateTransform Angle="45" />
</Button.LayoutTransform>
</Button>
<Button Content="A Button" Opacity="1" />
</StackPanel>
</Border>
Animazione delle trasformazioni
Poiché ereditano dalla classe Animatable, le classi Transform possono essere animate. Per animare un oggetto Transform, applicare un'animazione di un tipo compatibile alla proprietà che si desidera animare.
Nell'esempio seguente vengono utilizzati Storyboard e DoubleAnimation con RotateTransform per far girare un oggetto Button sul posto quando viene selezionato con un clic del mouse.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="Button Animated RotateTransform Example"
Background="White" Margin="50">
<StackPanel>
<Button Content="A Button"
RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
To="360" Duration="0:0:1" FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</Page>
Per l'esempio completo, vedere Esempio di trasformazioni bidimensionali (la pagina potrebbe essere in inglese). Per ulteriori informazioni sulle animazioni, vedere Cenni preliminari sull'animazione.
Funzionalità dell'oggetto Freezable
Poiché eredita dalla classe Freezable, la classe Transform fornisce diverse funzionalità speciali: gli oggetti Transform possono essere dichiarati come risorse, condivisi tra più oggetti, impostati in sola lettura per migliorare le prestazioni, duplicati e resi thread-safe. Per ulteriori informazioni sulle diverse funzionalità rese disponibili dagli oggetti Freezable, vedere Cenni preliminari sugli oggetti Freezable.