Delen via


Uw XAML-indeling optimaliseren

Belangrijke API's

Indeling is het proces voor het definiëren van de visuele structuur voor uw gebruikersinterface. Het primaire mechanisme voor het beschrijven van de indeling in XAML is via panelen. Dit zijn containerobjecten waarmee u de UI-elementen erin kunt plaatsen en rangschikken. Indeling kan een duur onderdeel zijn van een WinUI-app, zowel in CPU-gebruik als geheugenoverhead. Hier volgen enkele eenvoudige stappen die u kunt uitvoeren om de lay-outprestaties van uw WinUI-app te verbeteren.

Indelingsstructuur verminderen

De grootste winst in lay-out prestaties komt van het vereenvoudigen van de hiërarchische structuur van UI-elementen. Panelen bestaan in de visuele structuur, maar zijn structurele elementen, geen pixel die elementen produceert zoals een knop of een rechthoek. Het vereenvoudigen van de structuur door het aantal niet-pixelproducerende elementen te verminderen, zorgt doorgaans voor een aanzienlijke toename van de prestaties.

Veel WinUI-interfaces worden geïmplementeerd door het nesten van panelen, wat resulteert in diepe, complexe structuren van panelen en elementen. Het is handig om panelen te nesten, maar in veel gevallen kan dezelfde gebruikersinterface worden bereikt met een complexer enkel paneel. Het gebruik van één paneel biedt betere prestaties.

Wanneer moet u de indelingsstructuur verminderen

Het verminderen van de indelingsstructuur op een triviale manier, bijvoorbeeld het verminderen van één geneste paneel van uw pagina op het hoogste niveau, heeft geen merkbaar effect.

De grootste prestatieverbeteringen zijn het verminderen van de indelingsstructuur die wordt herhaald in de gebruikersinterface, zoals in een ListView of GridView. Deze ItemsControl-elementen maken gebruik van een DataTemplate, waarmee een substructuur wordt gedefinieerd van UI-elementen die vaak worden geïnstantieerd. Wanneer dezelfde substructuur meerdere keren in uw app wordt gedupliceerd, hebben verbeteringen in de prestaties van die substructuur een vermenigvuldigingseffect op de algehele prestaties van uw app.

Examples

Houd rekening met de volgende gebruikersinterface.

Voorbeeld van formulierindeling

In deze voorbeelden ziet u drie manieren om dezelfde gebruikersinterface te implementeren. Elke implementatiekeuze resulteert in bijna identieke pixels op het scherm, maar verschilt aanzienlijk in de implementatiedetails.

Optie 1: Geneste StackPanel-elementen

Hoewel dit het eenvoudigste model is, maakt het gebruik van vijf paneelelementen en resulteert het in aanzienlijke overhead.

  <StackPanel>
  <TextBlock Text="Options:" />
  <StackPanel Orientation="Horizontal">
      <CheckBox Content="Power User" />
      <CheckBox Content="Admin" Margin="20,0,0,0" />
  </StackPanel>
  <TextBlock Text="Basic information:" />
  <StackPanel Orientation="Horizontal">
      <TextBlock Text="Name:" Width="75" />
      <TextBox Width="200" />
  </StackPanel>
  <StackPanel Orientation="Horizontal">
      <TextBlock Text="Email:" Width="75" />
      <TextBox Width="200" />
  </StackPanel>
  <StackPanel Orientation="Horizontal">
      <TextBlock Text="Password:" Width="75" />
      <TextBox Width="200" />
  </StackPanel>
  <Button Content="Save" />
</StackPanel>

Optie 2: Eén raster

Het raster voegt enige complexiteit toe, maar gebruikt slechts één paneelelement.

<Grid>
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  <TextBlock Text="Options:" Grid.ColumnSpan="2" />
  <CheckBox Content="Power User" Grid.Row="1" Grid.ColumnSpan="2" />
  <CheckBox Content="Admin" Margin="150,0,0,0" Grid.Row="1" Grid.ColumnSpan="2" />
  <TextBlock Text="Basic information:" Grid.Row="2" Grid.ColumnSpan="2" />
  <TextBlock Text="Name:" Width="75" Grid.Row="3" />
  <TextBox Width="200" Grid.Row="3" Grid.Column="1" />
  <TextBlock Text="Email:" Width="75" Grid.Row="4" />
  <TextBox Width="200" Grid.Row="4" Grid.Column="1" />
  <TextBlock Text="Password:" Width="75" Grid.Row="5" />
  <TextBox Width="200" Grid.Row="5" Grid.Column="1" />
  <Button Content="Save" Grid.Row="6" />
</Grid>

Optie 3: Één RelativePanel

Dit enkele paneel is ook iets complexer dan het gebruik van geneste panelen, maar is mogelijk gemakkelijker te begrijpen en te onderhouden dan een raster.

<RelativePanel>
  <TextBlock Text="Options:" x:Name="Options" />
  <CheckBox Content="Power User" x:Name="PowerUser" RelativePanel.Below="Options" />
  <CheckBox Content="Admin" Margin="20,0,0,0" 
            RelativePanel.RightOf="PowerUser" RelativePanel.Below="Options" />
  <TextBlock Text="Basic information:" x:Name="BasicInformation"
           RelativePanel.Below="PowerUser" />
  <TextBlock Text="Name:" RelativePanel.AlignVerticalCenterWith="NameBox" />
  <TextBox Width="200" Margin="75,0,0,0" x:Name="NameBox"               
           RelativePanel.Below="BasicInformation" />
  <TextBlock Text="Email:"  RelativePanel.AlignVerticalCenterWith="EmailBox" />
  <TextBox Width="200" Margin="75,0,0,0" x:Name="EmailBox"
           RelativePanel.Below="NameBox" />
  <TextBlock Text="Password:" RelativePanel.AlignVerticalCenterWith="PasswordBox" />
  <TextBox Width="200" Margin="75,0,0,0" x:Name="PasswordBox"
           RelativePanel.Below="EmailBox" />
  <Button Content="Save" RelativePanel.Below="PasswordBox" />
</RelativePanel>

Zoals deze voorbeelden laten zien, zijn er veel manieren om dezelfde gebruikersinterface te bereiken. U moet ervoor kiezen door zorgvuldig rekening te houden met alle afwegingen, waaronder prestaties, leesbaarheid en onderhoudbaarheid.

Rasters met één cel gebruiken voor overlappende gebruikersinterface

Een veelvoorkomende vereiste voor de gebruikersinterface is een indeling te hebben waarbij elementen elkaar overlappen. Normaal gesproken worden opvulling, marges, uitlijningen en transformaties gebruikt om de elementen op deze manier te positioneren. Het besturingselement XAML-raster is geoptimaliseerd om de lay-outprestaties te verbeteren voor elementen die overlappen.

Belangrijk Als u de verbetering wilt zien, gebruikt u een raster met één cel. Definieer geen RowDefinitions of ColumnDefinitions.

Examples

<Grid>
    <Ellipse Fill="Red" Width="200" Height="200" />
    <TextBlock Text="Test" 
               HorizontalAlignment="Center" 
               VerticalAlignment="Center" />
</Grid>

Tekst overliggend op een cirkel

<Grid Width="200" BorderBrush="Black" BorderThickness="1">
    <TextBlock Text="Test1" HorizontalAlignment="Left" />
    <TextBlock Text="Test2" HorizontalAlignment="Right" />
</Grid>

Twee tekstblokken in een raster

Gebruik de ingebouwde randeigenschappen van een deelvenster

De besturingselementen Grid, StackPanel, RelativePanel en ContentPresenter hebben ingebouwde randeigenschappen waarmee u een rand eromheen kunt tekenen zonder een extra randelement toe te voegen aan uw XAML. De nieuwe eigenschappen die ondersteuning bieden voor de ingebouwde rand zijn: BorderBrush, BorderThickness, CornerRadius en Padding. Elk van deze is een DependencyProperty, zodat u ze kunt gebruiken met bindingen en animaties. Ze zijn ontworpen als een volledige vervanging voor een afzonderlijk rand-element.

Als uw gebruikersinterface randelementen rond deze panelen bevat, gebruikt u in plaats daarvan de ingebouwde rand, waardoor een extra element wordt opgeslagen in de indelingsstructuur van uw app. Zoals eerder vermeld, kan dit een aanzienlijke besparing zijn, met name in het geval van herhaalde gebruikersinterface.

Examples

<RelativePanel BorderBrush="Red" BorderThickness="2" CornerRadius="10" Padding="12">
    <TextBox x:Name="textBox1" RelativePanel.AlignLeftWithPanel="True"/>
    <Button Content="Submit" RelativePanel.Below="textBox1"/>
</RelativePanel>

SizeChanged-gebeurtenissen gebruiken om te reageren op wijzigingen in de indeling

De FrameworkElement-klasse bevat twee vergelijkbare gebeurtenissen voor het reageren op wijzigingen in de indeling: LayoutUpdated en SizeChanged. Mogelijk gebruikt u een van deze gebeurtenissen om een melding te ontvangen wanneer het formaat van een element tijdens de indeling wordt gewijzigd. De semantiek van de twee gebeurtenissen verschilt en er zijn belangrijke prestatieoverwegingen bij het kiezen tussen deze gebeurtenissen.

Voor goede prestaties is SizeChanged vrijwel altijd de juiste keuze. SizeChanged heeft intuïtieve semantiek. Deze wordt verhoogd tijdens de indeling wanneer de grootte van het FrameworkElement is bijgewerkt.

LayoutUpdated wordt ook gegenereerd tijdens de indeling, maar heeft globale semantiek. Deze wordt op elk element weergegeven wanneer een element wordt bijgewerkt. Het is gebruikelijk om alleen lokale verwerking uit te voeren in de gebeurtenishandler. In dat geval wordt de code vaker uitgevoerd dan nodig is. Gebruik LayoutUpdated alleen als u wilt weten wanneer een element wordt verplaatst zonder de grootte te wijzigen (wat ongebruikelijk is).

Kiezen tussen panelen

Prestaties zijn doorgaans geen overweging bij het kiezen tussen afzonderlijke panelen. Deze keuze wordt meestal gemaakt door te overwegen welk deelvenster het lay-outgedrag biedt dat zich het dichtst bij de gebruikersinterface bevindt die u implementeert. Als u bijvoorbeeld kiest tussen Grid, StackPanel en RelativePanel, moet u het paneel kiezen dat de dichtstbijzijnde toewijzing biedt aan uw mentale model van de implementatie.

Elk XAML-paneel is geoptimaliseerd voor goede prestaties en alle panelen bieden vergelijkbare prestaties voor vergelijkbare gebruikersinterface.