Ottimizzare il layout XAMLOptimize your XAML layout

API importantiImportant APIs

Il layout è il processo di definizione della struttura visiva dell'interfaccia utente.Layout is the process of defining the visual structure for your UI. Il meccanismo principale per la descrizione del layout in XAML usa i pannelli, che sono oggetti contenitore in cui puoi posizionare e disporre gli elementi dell'interfaccia utente.The primary mechanism for describing layout in XAML is through panels, which are container objects that enable you to position and arrange the UI elements within them. Il layout può essere una parte dispendiosa di un'app XAML, per quanto riguarda uso della CPU e sovraccarico della memoria.Layout can be an expensive part of a XAML app—both in CPU usage and memory overhead. Ecco alcuni semplici passaggi per migliorare le prestazioni di layout nella tua app XAML.Here are some simple steps you can take to improve the layout performance of your XAML app.

Ridurre la struttura di layoutReduce layout structure

Il miglioramento principale per le prestazioni di layout viene realizzato semplificando l'organizzazione gerarchica della struttura ad albero degli elementi dell'interfaccia utente.The biggest gain in layout performance comes from simplifying the hierarchical structure of the tree of UI elements. I pannelli sono inclusi nella struttura ad albero visuale, ma sono elementi strutturali e non elementi che producono pixel come Button o Rectangle.Panels exist in the visual tree, but they are structural elements, not pixel producing elements like a Button or a Rectangle. La semplificazione della struttura ad albero attraverso la riduzione del numero di elementi che non producono pixel offre in genere un miglioramento significativo delle prestazioni.Simplifying the tree by reducing the number of non-pixel-producing elements typically provides a significant performance increase.

Molte interfacce utente vengono implementate tramite l'annidamento di pannelli, che produce strutture ad albero di pannelli ed elementi complesse e ingombranti.Many UIs are implemented by nesting panels which results in deep, complex trees of panels and elements. L'annidamento dei pannelli è efficace, ma in molti casi la stessa interfaccia utente può essere ottenuta con un unico pannello più complesso.It is convenient to nest panels, but in many cases the same UI can be achieved with a more complex single panel. L'uso di un unico pannello offre prestazioni migliori.Using a single panel provides better performance.

Quando ridurre la struttura di layoutWhen to reduce layout structure

La riduzione della struttura di layout in modo banale, ad esempio riducendo un pannello annidato dalla pagina di primo livello, non ha un effetto visibile.Reducing layout structure in a trivial way—for example, reducing one nested panel from your top-level page—does not have a noticeable effect.

Le prestazioni migliori si ottengono riducendo la struttura di layout ripetuta nell’interfaccia utente, ad esempio in un elemento ListView o GridView.The largest performance gains come from reducing layout structure that's repeated in the UI, like in a ListView or GridView. Questi elementi ItemsControl usano un oggetto DataTemplate, che definisce un sottoalbero di elementi dell’interfaccia utente di cui viene creata un’istanza molte volte.These ItemsControl elements use a DataTemplate, which defines a subtree of UI elements that is instantiated many times. Quando lo stesso sottoalbero viene duplicato molte volte nell'app, qualsiasi miglioramento delle prestazioni di questo sottoalbero ha un effetto esponenziale sulle prestazioni complessive della tua app.When the same subtree is being duplicated many times in your app, any improvements to the performance of that subtree has a multiplicative effect on the overall performance of your app.

EsempiExamples

Considera l'interfaccia utente seguente.Consider the following UI.

Esempio di layout di modulo

Questi esempi mostrano tre modi di implementare la stessa interfaccia utente.These examples shows 3 ways of implementing the same UI. Ognuna delle scelte di implementazione produce pixel quasi identici sullo schermo, ma differisce sostanzialmente nei dettagli di implementazione.Each implementation choice results in nearly identical pixels on the screen, but differs substantially in the implementation details.

Opzione 1: elementi StackPanel annidatiOption1: Nested StackPanel elements

Nonostante sia il modello più semplice, usa 5 elementi pannello e produce un sovraccarico significativo.Although this is the simplest model, it uses 5 panel elements and results in significant 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>

Opzione 2: un unico elemento GridOption 2: A single Grid

L’elemento Grid aggiunge una certa complessità, ma usa un solo elemento pannello.The Grid adds some complexity, but uses only a single panel element.

<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>

Opzione 3: un unico elemento RelativePanelOption 3: A single RelativePanel:

Anche questo unico pannello è leggermente più complesso in confronto all’uso di pannelli annidati, ma può rivelarsi più facile da comprendere e gestire rispetto a un elemento Grid.This single panel is also a bit more complex than using nested panels, but may be easier to understand and maintain than a Grid.

<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>

Come mostra l'esempio, esistono molti modi di realizzare la stessa interfaccia utente.As these examples show, there are many ways of achieving the same UI. La tua scelta deve essere determinata da un'attenta considerazione di tutti i compromessi, ad esempio riguardo a prestazioni, leggibilità e gestibilità.You should choose by carefully considering all the tradeoffs, including performance, readability, and maintainability.

Usare griglie a una cella per gli elementi dell'interfaccia utente che si sovrappongonoUse single-cell grids for overlapping UI

Un requisito comune per l'interfaccia utente consiste nel creare un layout in cui gli elementi si sovrappongono gli uni agli altri.A common UI requirement is to have a layout where elements overlap each other. Per posizionare gli elementi in questo modo, vengono usati in genere spaziatura interna, margini, allineamenti e trasformazioni.Typically padding, margins, alignments, and transforms are used to position the elements this way. Il controllo Grid XAML è ottimizzato per migliorare le prestazioni di layout per gli elementi che si sovrappongono.The XAML Grid control is optimized to improve layout performance for elements that overlap.

Importante  Per osservare un miglioramento, usa un elemento Grid a una cella.Important  To see the improvement, use a single-cell Grid. Non definire RowDefinitions o ColumnDefinitions.Do not define RowDefinitions or ColumnDefinitions.

EsempiExamples

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

Testo sovrapposto a un cerchio

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

Due blocchi di testo in una griglia

Usare le proprietà del bordo predefinito di un pannelloUse a panel's built-in border properties

I controlli Grid, StackPanel, RelativePanel e ContentPresenter hanno proprietà per un bordo predefinito che ti permettono di disegnare un bordo attorno a tali controlli senza dover aggiungere un altro elemento Border al codice XAML.Grid, StackPanel, RelativePanel, and ContentPresenter controls have built-in border properties that let you draw a border around them without adding an additional Border element to your XAML. Le nuove proprietà che supportano il bordo predefinito sono: BorderBrush, BorderThickness, CornerRadius e Padding.The new properties that support the built-in border are: BorderBrush, BorderThickness, CornerRadius, and Padding. Dato che ognuna di queste proprietà è un oggetto DependencyProperty, puoi usarle con associazioni e animazioni.Each of these is a DependencyProperty, so you can use them with bindings and animations. Le proprietà sono progettate per sostituire completamente un elemento Border separato.They’re designed to be a full replacement for a separate Border element.

Se la tua interfaccia utente ha elementi Border attorno ai pannelli, usa il bordo predefinito al loro posto, in modo da fare a meno di un elemento aggiuntivo nella struttura di layout dell’app.If your UI has Border elements around these panels, use the built-in border instead, which saves an extra element in the layout structure of your app. Come accennato prima, può trattarsi di un risparmio significativo, in particolare in caso di interfaccia utente ripetuta.As mentioned previously, this can be a significant savings, especially in the case of repeated UI.

EsempiExamples

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

Usa eventi SizeChanged per rispondere alle modifiche di layoutUse SizeChanged events to respond to layout changes

La classe FrameworkElement espone due eventi simili per rispondere alle modifiche di layout: LayoutUpdated e SizeChanged.The FrameworkElement class exposes two similar events for responding to layout changes: LayoutUpdated and SizeChanged. Potresti usare uno di questi eventi per ricevere una notifica quando un elemento viene ridimensionato durante il layout.You might be using one of these events to receive notification when an element is resized during layout. La semantica dei due eventi è diversa e nello scegliere quale usare dovrai valutare alcune considerazioni importanti sulle prestazioni.The semantics of the two events are different, and there are important performance considerations in choosing between them.

Per ottenere buone prestazioni, SizeChanged è quasi sempre la scelta giusta.For good performance, SizeChanged is almost always the right choice. SizeChanged ha una semantica intuitiva.SizeChanged has intuitive semantics. Questo oggetto viene generato durante il layout una volta aggiornate le dimensioni di FrameworkElement.It is raised during layout when the size of the FrameworkElement has been updated.

Anche LayoutUpdated viene generato durante il layout, ma ha una semantica globale, ovvero viene generato su ogni elemento all'aggiornamento dell'elemento.LayoutUpdated is also raised during layout, but it has global semantics—it is raised on every element whenever any element is updated. L'elaborazione locale viene eseguita in genere nel gestore dell'evento e in questo caso il codice viene eseguito più spesso del necessario.It is typical to only do local processing in the event handler, in which case the code is run more often than needed. Usa LayoutUpdated solo se devi poter determinare il momento in cui un elemento viene riposizionato senza alcuna modifica delle dimensioni (che è un caso poco comune).Use LayoutUpdated only if you need to know when an element is repositioned without changing size (which is uncommon).

Scelta tra pannelliChoosing between panels

In genere, le prestazioni non vengono considerate quando si sceglie tra singoli pannelli.Performance is typically not a consideration when choosing between individual panels. Questa scelta è normalmente determinata dalla valutazione riguardo ai pannelli che forniscono il comportamento di layout più vicino all'interfaccia utente implementata.That choice is typically made by considering which panel provides the layout behavior that is closest to the UI you’re implementing. Ad esempio, se scegli tra Grid, StackPanel e RelativePanel, opta per il pannello che fornisce il mapping più simile al tuo modello mentale dell’implementazione.For example, if you’re choosing between Grid, StackPanel , and RelativePanel, you should choose the panel that provides the closest mapping to your mental model of the implementation.

Ogni pannello XAML è ottimizzato per garantire buone prestazioni e tutti i pannelli offrono prestazioni equivalenti per interfacce utente simili.Every XAML panel is optimized for good performance, and all the panels provide similar performance for similar UI.