Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
API Importanti
Il layout è il processo di definizione della struttura visiva per l'interfaccia utente. Il meccanismo principale per descrivere il layout in XAML è costituito da pannelli, ovvero oggetti contenitore che consentono di posizionare e disporre gli elementi dell'interfaccia utente all'interno di essi. Il layout può essere una parte costosa di un'app WinUI, sia nell'utilizzo della CPU che nel sovraccarico della memoria. Ecco alcuni semplici passaggi che puoi eseguire per migliorare le prestazioni di layout dell'app WinUI.
Ridurre la struttura di layout
Il maggiore miglioramento delle prestazioni di layout deriva dalla semplificazione della struttura gerarchica dell'albero degli elementi dell'interfaccia utente. I pannelli sono presenti nell'albero visuale, ma sono elementi strutturali, non elementi che producono pixel come un Button o un Rectangle. Semplificando l'albero riducendo il numero di elementi non di produzione di pixel, in genere si ottiene un aumento significativo delle prestazioni.
Molte interfacce utente WinUI vengono implementate tramite l'annidamento dei pannelli, che comporta alberi profondi e complessi di pannelli ed elementi. È comodo annidare i pannelli, ma in molti casi la stessa interfaccia utente può essere ottenuta con un singolo pannello più complesso. L'uso di un singolo pannello offre prestazioni migliori.
Quando ridurre la struttura del layout
La riduzione della struttura del layout in modo semplice, ad esempio la riduzione di un pannello annidato dalla pagina di primo livello, non ha un effetto evidente.
Le prestazioni più elevate derivano dalla riduzione della struttura di layout ripetuta nell'interfaccia utente, ad esempio in un controllo ListView o GridView. Questi elementi ItemsControl usano un oggetto DataTemplate, che definisce un sottoalbero di elementi dell'interfaccia utente di cui viene creata un'istanza più volte. Quando lo stesso sottoalbero viene duplicato molte volte nell'app, eventuali miglioramenti alle prestazioni di tale sottoalbero hanno un effetto moltiplicativo sulle prestazioni complessive dell'app.
Examples
Si consideri l'interfaccia utente seguente.
Questi esempi illustrano 3 modi per implementare la stessa interfaccia utente. Ogni scelta di implementazione comporta pixel quasi identici sullo schermo, ma differisce sostanzialmente nei dettagli di implementazione.
Opzione 1: Elementi StackPanel annidati
Anche se questo è il modello più semplice, usa 5 elementi del pannello e comporta un sovraccarico significativo.
<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: una singola griglia
Grid aggiunge una certa complessità, ma usa solo un singolo elemento pannello.
<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 singolo RelativePanel
Questo singolo pannello è anche un po 'più complesso rispetto all'uso di pannelli annidati, ma può essere più facile da comprendere e gestire rispetto a un 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 illustrato in questi esempi, esistono molti modi per ottenere la stessa interfaccia utente. È consigliabile scegliere con attenzione considerando tutti i compromessi, tra cui prestazioni, leggibilità e manutenibilità.
Usare le griglie a cella singola per la sovrapposizione dell'interfaccia utente
Un requisito comune dell'interfaccia utente consiste nell'avere un layout in cui gli elementi si sovrappongono tra loro. In genere vengono utilizzati imbottitura, margini, allineamenti e trasformazioni per posizionare gli elementi in questo modo. Il controllo Griglia XAML è ottimizzato per migliorare le prestazioni di layout per gli elementi che si sovrappongono.
Importante Per visualizzare il miglioramento, usare una griglia a cella singola. Non definire RowDefinitions o ColumnDefinitions.
Examples
<Grid>
<Ellipse Fill="Red" Width="200" Height="200" />
<TextBlock Text="Test"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid Width="200" BorderBrush="Black" BorderThickness="1">
<TextBlock Text="Test1" HorizontalAlignment="Left" />
<TextBlock Text="Test2" HorizontalAlignment="Right" />
</Grid>
Usare le proprietà predefinite del bordo di un pannello
I controlli Grid, StackPanel, RelativePanel e ContentPresenter includono proprietà del bordo predefinite che consentono di disegnare un bordo intorno a essi senza aggiungere un elemento Border aggiuntivo al codice XAML. Le nuove proprietà che supportano il bordo predefinito sono BorderBrush, BorderThickness, CornerRadius e Padding. Ognuna di queste è una DependencyProperty, quindi puoi usarla con collegamenti e animazioni. Sono progettati per essere una sostituzione completa per un elemento Border separato.
Se l'interfaccia utente include elementi Border intorno a questi pannelli, usa invece il bordo predefinito, che salva un elemento aggiuntivo nella struttura di layout della tua app. Come accennato in precedenza, questo può essere un risparmio significativo, soprattutto nel caso di interfaccia utente ripetuta.
Examples
<RelativePanel BorderBrush="Red" BorderThickness="2" CornerRadius="10" Padding="12">
<TextBox x:Name="textBox1" RelativePanel.AlignLeftWithPanel="True"/>
<Button Content="Submit" RelativePanel.Below="textBox1"/>
</RelativePanel>
Usare gli eventi SizeChanged per rispondere alle modifiche del layout
La classe FrameworkElement espone due eventi simili per rispondere alle modifiche di layout: LayoutUpdated e SizeChanged. È possibile usare uno di questi eventi per ricevere una notifica quando un elemento viene ridimensionato durante il layout. La semantica dei due eventi è diversa e vi sono importanti considerazioni sulle prestazioni nella scelta tra di esse.
Per prestazioni ottimali, SizeChanged è quasi sempre la scelta giusta. SizeChanged ha una semantica intuitiva. Viene generato durante il layout quando le dimensioni di FrameworkElement sono state aggiornate.
LayoutUpdated viene generato anche durante il layout, ma ha una semantica globale, che viene generata in ogni elemento ogni volta che viene aggiornato qualsiasi elemento. In genere viene eseguita solo l'elaborazione locale nel gestore eventi, nel qual caso il codice viene eseguito più spesso del necessario. Usare LayoutUpdated solo se è necessario sapere quando un elemento viene riposizionato senza modificare le dimensioni (che non è comune).
Scelta tra i pannelli
Le prestazioni non sono in genere una considerazione quando si sceglie tra singoli pannelli. Questa scelta viene in genere effettuata considerando il pannello che fornisce il comportamento di layout più vicino all'interfaccia utente che si sta implementando. Ad esempio, se scegli tra Grid, StackPanel e RelativePanel, devi scegliere il pannello che fornisce il mapping più vicino al modello mentale dell'implementazione.
Ogni pannello XAML è ottimizzato per prestazioni ottimali e tutti i pannelli offrono prestazioni simili per un'interfaccia utente simile.