Översikt över transformeringar

Lär dig hur du använder transformeringar i Windows Runtime-API:et genom att ändra de relativa koordinatsystemen för element i användargränssnittet. Detta kan användas för att justera utseendet på enskilda XAML-element, till exempel skalning, rotation eller transformering av positionen i x-y-utrymme.

Vad är en transformering?

En transformering definierar hur du mappar, eller transformerar, punkter från ett koordinatutrymme till ett annat koordinatutrymme. När en transformering tillämpas på ett gränssnittselement ändras hur användargränssnittselementet återges på skärmen som en del av användargränssnittet.

Tänk på transformeringar i fyra breda klassificeringar: översättning, rotation, skalning och skevhet (eller skjuvning). I syfte att använda grafik-API:er för att ändra utseendet på gränssnittselement är det vanligtvis enklast att skapa transformeringar som bara definierar en åtgärd i taget. Windows Runtime definierar därför en diskret klass för var och en av dessa transformeringsklassificeringar:

Av dessa använder du förmodligen TranslateTransform och ScaleTransform oftast för användargränssnittsscenarier.

Du kan kombinera transformeringar och det finns två Windows Runtime-klasser som stöder detta: CompositeTransform och TransformGroup. I en CompositeTransform tillämpas transformeringar i den här ordningen: skala, skeva, rotera, översätta. Använd TransformGroup i stället för CompositeTransform om du vill att transformeringarna ska tillämpas i en annan ordning. Mer information finns i CompositeTransform.

transformationer och layout

I XAML-layouten tillämpas transformeringar när layoutpasset har slutförts, så tillgängliga utrymmesberäkningar och andra layoutbeslut har fattats innan transformeringarna tillämpas. Eftersom layouten kommer först får du ibland oväntade resultat om du transformerar element som finns i en rutnätscell eller liknande layoutcontainer som allokerar utrymme under layouten. Det transformerade elementet kan verka trunkerat eller dolt eftersom det försöker dra till ett område som inte beräknar dimensionerna efter transformering när utrymmet delas upp i den överordnade containern. Du kan behöva experimentera med transformeringsresultaten och justera vissa inställningar. I stället för att förlita dig på exempelvis adaptiv layout och stjärnmått kan du behöva ändra egenskaperna för Center eller deklarera fasta pixelmått för layoututrymme för att säkerställa att det överordnade objektet allokerar tillräckligt med utrymme.

Migreringsanteckning: Windows Presentation Foundation (WPF) hade en LayoutTransform-egenskap som tillämpade transformeringar före layoutpasset. Men Windows Runtime XAML stöder inte en LayoutTransform-egenskap . (Microsoft Silverlight hade inte heller den här egenskapen.)

Tips/Råd

Som ett alternativ tillhandahåller Windows Community Toolkit layouttransformControl som tillämpar matristransformeringar på alla FrameworkElement i ditt program.

Tillämpa en transformering på ett användargränssnittselement

När du tillämpar en transformering på ett objekt gör du det vanligtvis för att ange egenskapen UIElement.RenderTransform. Om du anger den här egenskapen ändras inte objektets pixel per pixel. Vad egenskapen verkligen gör är att tillämpa transformering inom det lokala koordinatutrymmet där objektet finns. Sedan återger återgivningslogik och -åtgärden (efter layout) de kombinerade koordinatutrymmena, vilket gör att det ser ut som om objektet har ändrat utseende och även potentiellt dess layoutposition (om TranslateTransform tillämpades).

Som standard är varje återgivningstransformering centrerad på ursprunget till målobjektets lokala koordinatsystem – dess (0,0). Det enda undantaget är en TranslateTransform, som inte har några mittegenskaper att ange eftersom översättningseffekten är densamma oavsett var den är centrerad. Men de andra transformerna har egenskaper som anger CenterX - och CenterY-värden .

När du använder transformeringar med UIElement.RenderTransform ska du komma ihåg att det finns en annan egenskap i UIElement som påverkar hur transformering fungerar: RenderTransformOrigin. Vad RenderTransformOrigin deklarerar är om hela transformeringen ska gälla för standardpunkten (0,0) för ett element eller någon annan ursprungspunkt inom elementets relativa koordinatutrymme. För typiska element placerar (0,0) transformeringen i det övre vänstra hörnet. Beroende på vilken effekt du vill ha kan du välja att ändra RenderTransformOrigin i stället för att justera CenterX - och CenterY-värdena på transformeringar. Observera att om du använder både RenderTransformOrigin - och CenterX / CenterY-värden kan resultatet vara ganska förvirrande, särskilt om du animera något av värdena.

För syftet med träfftestning fortsätter ett objekt som en transformering tillämpas på att reagera på indata på ett förväntat sätt som är i linje med dess visuella utseende i x-y-utrymme. Om du till exempel har använt en TranslateTransform- för att flytta en Rektangel 400 bildpunkter i sidled i användargränssnittet, svarar RektangelnPointerPressed--händelser när användaren trycker på den punkt där Rektangeln visas visuellt. Du får inte falska händelser om användaren trycker på området där Rektangel var innan den översattes. För eventuella z-indexöverväganden som påverkar träfftestning spelar det ingen roll att tillämpa en transformering; z-indexet som styr vilket element som hanterar indatahändelser för en punkt i x-y-rymden utvärderas fortfarande med hjälp av barnordningen som deklarerats i en behållare. Den ordningen är vanligtvis samma som i vilken ordning du deklarerar elementen i XAML, men för underordnade element i ett Canvas-objekt kan du justera ordningen genom att använda egenskapen Canvas.ZIndex kopplat till underordnade element.

Andra transformeringsegenskaper

  • Brush.Transform, Brush.RelativeTransform: Dessa påverkar hur en pensel använder koordinatutrymme inom det område som penseln används för att ange visuella egenskaper, till exempel förgrunder och bakgrunder. Dessa transformeringar är inte relevanta för de vanligaste penslar (som vanligtvis ställer in solida färger med SolidColorBrush) men kan ibland vara användbara när du målar områden med en ImageBrush eller LinearGradientBrush.
  • Geometry.Transform: Du kan använda den här egenskapen för att tillämpa en transformering på en geometri innan du använder den geometrin som ett egenskapsvärde för en Path.Data.

Animera en transformation

Transform objekt kan animeras. För att animera en transformering, använd en animation av en kompatibel typ på den egenskap du vill animera. Det innebär vanligtvis att du använder DoubleAnimation - eller DoubleAnimationUsingKeyFrames-objekt för att definiera animeringen, eftersom alla transformeringsegenskaper är av typen Double. Animeringar som påverkar en transform som används för ett UIElement.RenderTransform-värde anses inte vara beroende animeringar, även om de har en varaktighet som inte är noll. Mer information om beroende animeringar finns i Storyboarded-animeringar.

Om du animerar egenskaper för att skapa en effekt som liknar en transformering när det gäller det visuella nettoutseendet, till exempel att animera bredd och höjd för ett FrameworkElement i stället för att tillämpa en TranslateTransform, behandlas sådana animeringar nästan alltid som beroende animeringar. Du måste aktivera animeringarna och det kan uppstå betydande prestandaproblem med animeringen, särskilt om du försöker stödja användarinteraktion medan objektet animerats. Därför är det bättre att använda en transformering och animera den i stället för att animera någon annan egenskap där animeringen skulle behandlas som en beroende animering.

Om du vill rikta in omvandlingen måste det finnas en befintlig Transform som ett värde för RenderTransform. Du placerar vanligtvis ett element för lämplig transformeringstyp i den första XAML-filen, ibland utan att några egenskaper har angetts för den transformeringen.

Du använder vanligtvis en teknik för indirekt inriktning för att tillämpa animeringar på egenskaperna för en transformering. Mer information om indirekt målsyntax finns i animationsberättelser och egenskapssökvägssyntax.

Standardstilar för kontroller definierar ibland animationer av transformationer som en del av deras beteende för visuella tillstånd. Till exempel använder de visuella tillstånden för ProgressRing animerade RotateTransform värden för att "snurra" punkterna i ringen.

Här är ett enkelt exempel på hur du animerar en transformering. I det här fallet animeras -vinkel hos en RotateTransform för att snurra en Rektangel i sin plats runt dess visuella centrum. I det här exemplet namnges RotateTransform, så att indirekt målinriktning för animation inte behövs, men du kan också lämna transformen namnlös, namnge det element som transformen tillämpas på och använda indirekt målinriktning, till exempel (UIElement.RenderTransform).(RotateTransform.Angle).

<StackPanel Margin="15">
  <StackPanel.Resources>
    <Storyboard x:Name="myStoryboard">
      <DoubleAnimation
       Storyboard.TargetName="myTransform"
       Storyboard.TargetProperty="Angle"
       From="0" To="360" Duration="0:0:5" 
       RepeatBehavior="Forever" />
    </Storyboard>
  </StackPanel.Resources>
  <Rectangle Width="50" Height="50" Fill="RoyalBlue"
   PointerPressed="StartAnimation">
    <Rectangle.RenderTransform>
      <RotateTransform x:Name="myTransform" Angle="45" CenterX="25" CenterY="25" />
    </Rectangle.RenderTransform>
  </Rectangle>
</StackPanel>
void StartAnimation (object sender, RoutedEventArgs e) {
    myStoryboard.Begin();
}

Hantering av koordinatreferensramar vid körning

UIElement har en metod med namnet TransformToVisual, som kan generera en Transform som sammanlänkar referensramarna för två UI-element. Du kan använda detta för att jämföra ett element mot appens standardkoordinatsystem om det visuella rotobjektet skickas som den första parametern. Detta kan vara användbart om du har avbildat en indatahändelse från ett annat element, eller om du försöker förutsäga layoutbeteende utan att faktiskt begära ett layoutpass.

Anmärkning

(UWP) Händelsedata som hämtas från pekarhändelser ger åtkomst till en GetCurrentPoint-metod , där du kan ange en relativeTo-parameter för att ändra referensramen till ett specifikt element i stället för appens standard. Den här metoden tillämpar helt enkelt en översättningstransformering internt och transformerar x-y-koordinatdata åt dig när det returnerade PointerPoint-objektet skapas.

Beskriva en transformering matematiskt

En transformering kan beskrivas i termer av en transformeringsmatris. En 3×3-matris används för att beskriva omvandlingarna i ett tvådimensionellt x-y-plan. Affintransformationsmatriser kan multipliceras så att de bildar valfritt antal linjära transformeringar, till exempel rotation och skevhet (skjuvning), följt av översättning. Den sista kolumnen i en affintransformeringsmatris är lika med (0, 0, 1), så du behöver bara ange medlemmarna i de två första kolumnerna i den matematiska beskrivningen.

Den matematiska beskrivningen av en transformering kan vara användbar för dig om du har en matematisk bakgrund eller en förtrogenhet med grafikprogrammeringstekniker som också använder matriser för att beskriva transformeringar av koordinatutrymme. Det finns en Transform-avledd klass som gör att du kan uttrycka en transformation direkt i form av dess 3×3 matris: MatrixTransform. MatrixTransform har en matrisegenskap som innehåller en struktur som har sex egenskaper: M11, M12, M21, M22, OffsetX och OffsetY. Varje egenskap i -matrisen använder ett -värde av typen Double och motsvarar de sex relevanta värdena i en affintransformationsmatris (kolumn 1 och 2).

Kolumn 1 Kolumn 2 Kolumn 3
M11 M12 0
M21 M22 0
OffsetX FörskjutningY 1

Alla transformeringar som du kan beskriva med ett TranslateTransform-, ScaleTransform-, RotateTransform- eller SkewTransform-objekt kan beskrivas lika av en MatrixTransform med ett matrisvärde . Men du använder vanligtvis bara TranslateTransform och de andra eftersom egenskaperna för dessa transformeringsklasser är enklare att konceptualisera än att ange vektorkomponenterna i en matris. Det är också enklare att animera de diskreta egenskaperna för transformeringar. en matris är faktiskt en struktur och inte en DependencyObject, så den kan inte stödja animerade enskilda värden.

Vissa XAML-designverktyg som gör att du kan använda transformeringsåtgärder serialiserar resultatet som en MatrixTransform. I det här fallet kan det vara bäst att använda samma designverktyg igen för att ändra transformeringseffekten och serialisera XAML igen, i stället för att försöka manipulera matrisvärdena själv direkt i XAML.

3D-transformeringar

I Windows 10 introducerade XAML en ny egenskap, UIElement.Transform3D, som kan användas för att skapa 3D-effekter med användargränssnittet. Det gör du genom att använda PerspectiveTransform3D för att lägga till ett delat 3D-perspektiv eller en "kamera" i scenen och sedan använda CompositeTransform3D för att transformera ett element i 3D-utrymme, som du skulle använda CompositeTransform. Mer information om hur du implementerar 3D-transformeringar finns i UIElement.Transform3D .

För enklare 3D-effekter som endast gäller för ett enskilt objekt kan egenskapen UIElement.Projection användas. Att använda en PlaneProjection- som värde för den här egenskapen motsvarar att tillämpa en transformering med fast perspektiv och en eller flera 3D-transformeringar på elementet. Den här typen av transformering beskrivs mer detaljerat i 3D-perspektiveffekter för XAML-användargränssnittet.