Pannelli di layout

I pannelli di layout sono contenitori che ti consentono di disporre e raggruppare gli elementi dell'interfaccia utente nella tua app. I pannelli di layout XAML predefiniti includono RelativePanel, StackPanel, Grid, VariableSizedWrapGrid e Canvas. Qui viene descritto ogni pannello e viene illustrato come usarlo per il layout degli elementi dell'interfaccia utente XAML.

Quando si sceglie un pannello di layout, è necessario considerare diversi aspetti:

  • In che modo il pannello posiziona i relativi elementi figlio.
  • In che modo il pannello dimensiona i relativi elementi figlio.
  • In che modo gli elementi figlio sovrapposti vengono risultano sovrapposti tra loro (ordine z).
  • Numero e complessità degli elementi del pannello annidati necessari per creare il layout desiderato.

Esempi

Raccolta WinUI 2
WinUI Gallery

Se è stata installata l'app Raccolta WinUI 2, vedere le classi RelativePanel, StackPanel, Grid, VariableSizedWrapGrid e Canvas in azione.

Proprietà dei pannelli

Prima di illustrare i singoli pannelli, esaminiamo alcune proprietà comuni a tutti i pannelli.

Proprietà associate al pannello

La maggior parte dei pannelli di layout XAML usa proprietà associate per consentire agli elementi figlio di informare il pannello padre su come devono essere posizionati nell'interfaccia utente. Le proprietà associate usano la sintassi AttachedPropertyProvider.PropertyName. Se sono presenti pannelli annidati all'interno di altri pannelli, le proprietà associate agli elementi dell'interfaccia utente che specificano le caratteristiche di layout per un elemento padre vengono interpretate solo dal pannello padre più immediato.

Di seguito è riportato un esempio di come impostare la proprietà associata Canvas.Left in un controllo Button in XAML. In questo modo l'elemento Canvas padre indica che il pulsante deve essere posizionato a 50 pixel effettivi dal bordo sinistro dell'oggetto Canvas.

<Canvas>
  <Button Canvas.Left="50">Hello</Button>
</Canvas>

Per ulteriori informazioni sulle proprietà associate, vedere Panoramica sulle proprietà associate.

Bordi del pannello

I pannelli RelativePanel, StackPanel e Grid definiscono le proprietà del bordo che consentono di disegnare un bordo intorno al pannello senza eseguirne il wrapping in un elemento Border aggiuntivo. Le proprietà del bordo sono BorderBrush, BorderThickness, CornerRadius e Padding.

Ecco un esempio di come impostare le proprietà del bordo in una Grid.

<Grid BorderBrush="Blue" BorderThickness="12" CornerRadius="12" Padding="12">
    <TextBlock Text="Hello World!"/>
</Grid>

A Grid with borders

L'uso delle proprietà predefinite del bordo riduce il numero di elementi XAML, il che permette di migliorare le prestazioni dell'interfaccia utente dell'app. Per ulteriori informazioni sui pannelli di layout e sulle prestazioni dell'interfaccia utente, vedere Ottimizzare il layout XAML.

RelativePanel

La classe RelativePanel consente di definire il layout degli elementi dell'interfaccia utente specificandone la posizione rispetto agli altri elementi e in relazione al pannello. Per impostazione predefinita, un elemento viene posizionato nell'angolo superiore sinistro del pannello. Puoi usare RelativePanel con VisualStateManager e AdaptiveTrigger per riorganizzare l'interfaccia utente per finestre di varie dimensioni.

In questa tabella vengono mostrate le proprietà associate che puoi usare per allineare un elemento al pannello o ad altri elementi.

Allineamento pannello Allineamento elementi di pari livello Posizione elementi di pari livello
AlignTopWithPanel AlignTopWith Above
AlignBottomWithPanel AlignBottomWith Below
AlignLeftWithPanel AlignLeftWith LeftOf
AlignRightWithPanel AlignRightWith RightOf
AlignHorizontalCenterWithPanel AlignHorizontalCenterWith  
AlignVerticalCenterWithPanel AlignVerticalCenterWith  

Questo codice XAML mostra come disporre gli elementi in un oggetto RelativePanel.

<RelativePanel BorderBrush="Gray" BorderThickness="1">
    <Rectangle x:Name="RedRect" Fill="Red" Height="44" Width="44"/>
    <Rectangle x:Name="BlueRect" Fill="Blue"
               Height="44" Width="88"
               RelativePanel.RightOf="RedRect" />

    <Rectangle x:Name="GreenRect" Fill="Green" 
               Height="44"
               RelativePanel.Below="RedRect" 
               RelativePanel.AlignLeftWith="RedRect" 
               RelativePanel.AlignRightWith="BlueRect"/>
    <Rectangle Fill="Orange"
               RelativePanel.Below="GreenRect" 
               RelativePanel.AlignLeftWith="BlueRect" 
               RelativePanel.AlignRightWithPanel="True"
               RelativePanel.AlignBottomWithPanel="True"/>
</RelativePanel>

Il risultato è simile al seguente.

Relative panel

Ecco alcune considerazioni di cui prendere nota in merito al ridimensionamento dei rettangoli:

  • Al rettangolo rosso viene assegnata una dimensione esplicita di 44x44. Viene posizionato nell'angolo superiore sinistro del pannello, ovvero la posizione predefinita.
  • Al rettangolo verde viene assegnata un'altezza esplicita di 44. Il suo lato sinistro è allineato al rettangolo rosso e il lato destro è allineato al rettangolo blu, che ne determina la larghezza.
  • Al rettangolo arancione non viene assegnata in modo esplicito una dimensione. Il suo lato sinistro è allineato al rettangolo blu. I suoi bordi destro e inferiore sono allineati al bordo del pannello. Le sue dimensioni sono determinate da questi allineamenti e verranno ridimensionate man mano che il pannello viene ridimensionato.

StackPanel

StackPanel dispone i propri elementi figlio su una sola riga con orientamento orizzontale o verticale. StackPanel viene in genere usato per disporre una piccola sottosezione dell'interfaccia utente in una pagina.

È possibile utilizzare la proprietà Orientation per specificare la direzione degli elementi figlio. L'orientamento predefinito è Verticale.

Il seguente codice XAML illustra come creare uno StackPanel verticale di elementi.

<StackPanel>
    <Rectangle Fill="Red" Height="44"/>
    <Rectangle Fill="Blue" Height="44"/>
    <Rectangle Fill="Green" Height="44"/>
    <Rectangle Fill="Orange" Height="44"/>
</StackPanel>

Il risultato è simile al seguente.

Stack panel

In uno StackPanel, se le dimensioni di un elemento figlio non sono impostate in modo esplicito questo si estende per riempire la larghezza disponibile (o l'altezza se Orientation è impostato a Horizontal). In questo esempio la larghezza dei rettangoli non è impostata. I rettangoli si espandono per riempire l'intera larghezza di StackPanel.

Griglia

Il pannello Grid supporta layout fluidi e ti consente di disporre i controlli in layout su più righe e colonne. Puoi specificare le righe e le colonne di un pannello Grid usando le proprietà RowDefinitions e ColumnDefinitions.

Per posizionare gli oggetti in celle specifiche dell'elemento Grid, usa le proprietà associate Grid.Column e Grid.Row.

Per estendere il contenuto su più righe e colonne, usa le proprietà associate Grid.RowSpan e Grid.ColumnSpan.

Questo esempio XAML mostra come creare una griglia con due righe e due colonne.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="44"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Rectangle Fill="Red" Width="44"/>
    <Rectangle Fill="Blue" Grid.Row="1"/>
    <Rectangle Fill="Green" Grid.Column="1"/>
    <Rectangle Fill="Orange" Grid.Row="1" Grid.Column="1"/>
</Grid>

Il risultato è simile al seguente.

Grid

In questo esempio il ridimensionamento funziona come segue:

  • La seconda riga ha un'altezza esplicita di 44 pixel effettivi. Per impostazione predefinita, l'altezza della prima riga riempie qualsiasi spazio rimasto libero.
  • La larghezza della prima colonna è impostata su Auto, quindi è larga quanto necessario per i relativi elementi figlio. In questo caso, è 44 pixel effettivi di larghezza per contenere la larghezza del rettangolo rosso.
  • Non esistono altri vincoli di dimensione sui rettangoli, quindi ognuno si estende per riempire la cella della griglia in cui si trova.

È possibile distribuire lo spazio all'interno di una colonna o di una riga usando il ridimensionamento Auto o star. Il ridimensionamento automatico ridimensiona gli elementi dell'interfaccia utente per adattarli al loro contenuto o al contenitore padre. È anche possibile usare il ridimensionamento automatico con le righe e le colonne di una griglia. Per usare il ridimensionamento automatico, impostare Height e/o Width degli elementi dell'interfaccia utente su Auto.

Il ridimensionamento proporzionale , detto anche dimensionamento star, distribuisce lo spazio disponibile tra le righe e le colonne di una griglia in base a proporzioni ponderate. In XAML i valori delle unità di ridimensionamento proporzionale sono espressi come* (o n* per il ridimensionamento proporzionale Star ponderato). Ad esempio, per specificare che una colonna è cinque volte più larga rispetto alla seconda colonna in un layout a due colonne, usa "5*" e "*" per le proprietà Larghezza negli elementi ColumnDefinition.

Questo esempio combina il ridimensionamento fisso, automatico e proporzionale in una griglia con 4 colonne.

Istogramma Dimensionamento Descrizione
Column_1 Auto La colonna verrà ridimensionata per adattarne il contenuto.
Column_2 * Dopo aver calcolato le colonne Auto, la colonna ottiene parte della larghezza rimanente. Column_2 avrà una larghezza pari a metà del Column_4.
Column_3 44 La colonna avrà una larghezza di 44 pixel.
Column_4 2* Dopo aver calcolato le colonne Auto, la colonna ottiene parte della larghezza rimanente. Column_4 sarà il doppio del Column_2.

La larghezza predefinita della colonna è "*", pertanto non è necessario impostare in modo esplicito questo valore per la seconda colonna.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
        <ColumnDefinition Width="44"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Column 1 sizes to its content." FontSize="24"/>
</Grid>

Nella finestra di progettazione XAML di Visual Studio il risultato è simile al seguente.

A 4 column grid in the Visual Studio designer

VariableSizedWrapGrid

VariableSizedWrapGrid è un pannello con layout a griglia in cui righe o colonne che vanno automaticamente a capo su un'altra riga o colonna quando viene raggiunto il valore MaximumRowsOrColumns.

La proprietà Orientation specifica se la griglia aggiunge gli elementi nelle righe o nelle colonne prima di andare a capo. L'orientamento predefinito è Verticale, ovvero la griglia aggiunge elementi dall'alto verso il basso fino a quando una colonna non è piena, quindi esegue va a capo in una nuova colonna. Quando il valore è Horizontal, la griglia aggiunge elementi da sinistra a destra, quindi va a capo in una nuova riga.

Le dimensioni delle celle vengono specificate da ItemHeight e ItemWidth. Ogni cella ha le stesse dimensioni. Se ItemHeight o ItemWidth non sono specificati, la prima cella viene ridimensionata per adattarne il contenuto e ogni altra cella corrisponde alla dimensione della prima cella.

È possibile usare le proprietà associate VariableSizedWrapGrid.ColumnSpan e VariableSizedWrapGrid.RowSpan per specificare il numero di celle adiacenti che un elemento figlio deve riempire.

Ecco come usare VariableSizedWrapGrid in XAML.

<VariableSizedWrapGrid MaximumRowsOrColumns="3" ItemHeight="44" ItemWidth="44">
    <Rectangle Fill="Red"/>
    <Rectangle Fill="Blue" 
               VariableSizedWrapGrid.RowSpan="2"/>
    <Rectangle Fill="Green" 
               VariableSizedWrapGrid.ColumnSpan="2"/>
    <Rectangle Fill="Orange" 
               VariableSizedWrapGrid.RowSpan="2" 
               VariableSizedWrapGrid.ColumnSpan="2"/>
</VariableSizedWrapGrid>

Il risultato è simile al seguente.

Variable size wrap grid

In questo esempio il numero massimo di righe in ogni colonna è 3. La prima colonna contiene solo 2 elementi (rettangoli rosso e blu) perché il rettangolo blu si estende su 2 righe. Il rettangolo verde viene quindi disposto nella parte superiore della colonna successiva.

Canvas

Il pannello Canvas posiziona gli elementi figlio usando punti fissi di coordinate e non supporta layout fluidi. Specificare i punti sui singoli elementi figlio impostando le proprietà associate Canvas.Left e Canvas.Top su ogni elemento. L'oggetto Canvas padre legge questi valori delle proprietà associate dai figli durante il calcolo Arrange del layout.

Gli oggetti in un oggetto Canvas possono sovrapporsi, ossia un oggetto può venire disegnato sopra un altro oggetto. Per impostazione predefinita, Canvas esegue il rendering degli oggetti figlio nell'ordine in cui sono dichiarati, quindi viene eseguito il rendering dell'ultimo elemento figlio in alto (ogni elemento ha un indice z predefinito pari a 0). Questo comportamento è lo stesso in altri pannelli predefiniti. Canvas supporta tuttavia anche la proprietà associata Canvas.ZIndex che è possibile impostare su ognuno degli elementi figlio. È possibile impostare questa proprietà nel codice per modificare l'ordine di disegno degli elementi durante l'esecuzione. L'elemento con il valore Canvas.ZIndex più alto disegna per ultimo e quindi disegna su tutti gli altri elementi che condividono lo stesso spazio o si sovrappongono in qualsiasi modo. Si noti che il valore alfa (trasparenza) viene rispettato, quindi, anche se gli elementi si sovrappongono, il contenuto mostrato nelle aree di sovrapposizione potrebbe essere mescolato se la parte superiore ha un valore alfa non impostato alla regolazione massima.

L'oggetto Canvas non esegue alcun ridimensionamento dei relativi elementi figlio. Ogni elemento deve specificare le proprie dimensioni.

Ecco un esempio di Canvas in XAML.

<Canvas Width="120" Height="120">
    <Rectangle Fill="Red" Height="44" Width="44"/>
    <Rectangle Fill="Blue" Height="44" Width="44" Canvas.Left="20" Canvas.Top="20"/>
    <Rectangle Fill="Green" Height="44" Width="44" Canvas.Left="40" Canvas.Top="40"/>
    <Rectangle Fill="Orange" Height="44" Width="44" Canvas.Left="60" Canvas.Top="60"/>
</Canvas>

Il risultato è simile al seguente.

Canvas

Usare il pannello Canvas con discrezione. Anche se è comodo essere in grado di controllare con precisione le posizioni degli elementi nell'interfaccia utente per alcuni scenari, un layout del pannello fisso fa sì che tale area dell'interfaccia utente sia meno in grado di adattarsi alle modifiche complessive delle dimensioni della finestra dell'app. Il ridimensionamento della finestra dell'app può avere origine da modifiche all'orientamento del dispositivo, dalla suddivisione delle finestre dell'app, dalla modifica del monitor e da diversi altri scenari utente.

Pannelli per ItemsControl

Esistono diversi pannelli speciali che possono essere usati solo come ItemsPanel per visualizzare gli elementi in itemsControl. Si tratta di ItemsStackPanel, ItemsWrapGrid, VirtualizingStackPanel e WrapGrid. Non è possibile usare questi pannelli per il layout generale dell'interfaccia utente.

Scaricare il codice di esempio