Aggiungere controlli visivi a un'app .NET MAUI

Completato

Ora che si è usato il modello .NET MAUI per creare l'applicazione, il passaggio successivo consiste nell'aggiungere l'interfaccia utente e implementare la logica dell'interfaccia utente iniziale.

In questa unità vengono fornite altre informazioni sui blocchi predefiniti di un'applicazione .NET MAUI (Multi-platform Application User Interface) e sulle strutture di layout.

Cosa include un progetto .NET MAUI?

Per riepilogare, un progetto .NET MAUI inizialmente contiene:

  • Il file MauiProgram.cs contenente il codice per la creazione e la configurazione dell'oggetto Application.

  • I file App.xaml e App.xaml.cs che forniscono le risorse dell'interfaccia utente e creano la finestra iniziale per l'applicazione.

  • I file AppShell.xaml e AppShell.xaml.cs che specificano la pagina iniziale per l'applicazione e gestiscono la registrazione delle pagine per il routing di spostamento.

  • I file MainPage.xaml e MainPage.xaml.cs che definiscono il layout e la logica dell'interfaccia utente per la pagina visualizzata per impostazione predefinita nella finestra iniziale.

È possibile aggiungere altre pagine all'app in base alle esigenze e creare classi aggiuntive per implementare la logica di business richiesta dall'app.

Un progetto .NET MAUI contiene anche un set predefinito di risorse dell'applicazione come immagini, icone e tipi di carattere e codice bootstrap predefinito per ogni piattaforma.

Classe Application

La classe App rappresenta l'applicazione .NET MAUI nel suo complesso. Eredita un set predefinito di comportamenti da Microsoft.Maui.Controls.Application. Come si ricorderà dall'unità precedente, è la classe App di cui viene creata un'istanza e che viene caricata dal codice bootstrap per ogni piattaforma. Il costruttore della classe App creerà, a sua volta, un'istanza della classe AppShell e la assegnerà alla proprietà MainPage. È questo codice che controlla la prima schermata visualizzata dall'utente in base alle definizioni in AppShell.

La classe App contiene anche:

  • Metodi per la gestione degli eventi del ciclo di vita, ad esempio quando l'app viene inviata in background (ovvero, quando cessa di essere l'app in primo piano).

  • Metodi per la creazione di nuovi elementi Windows per l'applicazione. L'applicazione .NET MAUI ha una sola finestra per impostazione predefinita, ma è possibile creare e avviare altre finestre, una funzionalità utile nelle applicazioni desktop e tablet.

Shell

.NET Multi-Platform App UI (.NET MAUI) Shell riduce la complessità legata allo sviluppo delle app fornendo le funzionalità fondamentali richieste dalla maggior parte delle app, tra cui:

  • Un'unica posizione per descrivere la gerarchia visiva di un'app.
  • Un'esperienza utente di navigazione comune.
  • Uno schema di spostamento basato su URI che consente la navigazione in qualsiasi pagina dell'app.
  • Un gestore di ricerca integrato.

In un'app .NET MAUI Shell la gerarchia visiva dell'app è descritta in una classe che include sottoclassi della classe Shell. Questa classe può essere costituita da tre oggetti gerarchici principali:

  • FlyoutItem o TabBar. Un elemento FlyoutItem rappresenta uno o più elementi del riquadro a comparsa e deve essere usato quando il modello di spostamento per l'app richiede un riquadro a comparsa. Un elemento TabBar rappresenta la barra delle schede inferiore e deve essere usato quando il modello di spostamento per l'app inizia con le schede inferiori e non richiede un riquadro a comparsa.
  • Tab, che rappresenta contenuto raggruppato, in cui è possibile spostarsi tramite le schede inferiori.
  • ShellContent, che rappresenta gli oggetti ContentPage per ogni scheda.

Questi oggetti non rappresentano un'interfaccia utente, ma l'organizzazione della gerarchia visiva dell'app. Shell prende questi oggetti e genera l'interfaccia utente di spostamento per il contenuto.

Pagine

Le pagine sono la radice della gerarchia dell'interfaccia utente in .NET MAUI all'interno di un Shell. Finora, la soluzione visualizzata include una classe denominata MainPage. Questa classe deriva da ContentPage, che è il tipo di pagina più semplice e più comune. Una pagina contenuto visualizza semplicemente il suo contenuto. .NET MAUI offre anche numerosi altri tipi di pagina predefiniti, tra cui:

  • TabbedPage: pagina radice usata per lo spostamento tra schede. Una pagina a schede contiene oggetti pagina figlio, uno per ogni scheda.

  • FlyoutPage: Consente di implementare una presentazione in stile master/dettaglio. Una pagina con riquadro a comparsa contiene un elenco di elementi. Quando si seleziona un elemento, compare una visualizzazione che mostra i dettagli dell'elemento.

Sono disponibili altri tipi di pagina, che vengono utilizzati principalmente per abilitare schemi di spostamento diversi nelle app con più schermate.

Visualizzazioni

Una pagina contenuto mostra in genere una visualizzazione. Una visualizzazione consente di recuperare e presentare i dati in modo specifico. La visualizzazione predefinita per una pagina contenuto è ContentView, che visualizza gli elementi così come sono. Se si riduce la visualizzazione, gli elementi potrebbero scomparire fino a quando la visualizzazione non viene ridimensionata. ScrollView consente di visualizzare gli elementi in una finestra di scorrimento; se si riduce la finestra è possibile scorrere verso l'alto e verso il basso per visualizzare gli elementi. CarouselView è una visualizzazione scorrevole che consente all'utente di scorrere rapidamente una raccolta di elementi. CollectionView può recuperare i dati da un'origine dati denominata e presentare ogni elemento usando un modello come formato. Sono disponibili anche molti altri tipi di visualizzazioni

Controlli e layout

Una visualizzazione può contenere un singolo controllo, come un pulsante, un'etichetta o caselle di testo. In senso stretto, una visualizzazione è di per sé un controllo, quindi può contenere un'altra visualizzazione. Tuttavia, un'interfaccia utente limitata a un singolo controllo non sarebbe così utile, quindi i controlli sono posizionati in un layout. Un layout definisce le regole in base alle quali i controlli vengono visualizzati uno rispetto all'altro. Un layout è anche un controllo, quindi è possibile aggiungerlo a una visualizzazione. Se si osserva il file predefinito MainPage.xaml, si vede questa gerarchia di pagina/visualizzazione/layout/controllo in azione. In questo codice XAML l'elemento VerticalStackLayout è solo un altro controllo che consente di ottimizzare il layout di altri controlli.

<ContentPage ...>
    <ScrollView ...>
        <VerticalStackLayout>
            <Image ... />
            <Label ... />
            <Label ... />
            <Button ... />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

Alcuni dei controlli comuni usati per definire i layout sono:

  • VerticalStackLayout e HorizontalStackLayout, layout pila ottimizzati che dispongono i controlli in una pila dall'alto verso il basso o da sinistra a destra. È disponibile anche un StackLayout, che ha una proprietà denominata StackOrientation impostabile su Horizontal o Vertical. In un tablet o un telefono la modifica di questa proprietà nel codice dell'applicazione consente di regolare la visualizzazione se l'utente ruota il dispositivo:

    Diagramma che mostra in che modo verranno disposti i controlli in base all'orientamento orizzontale e verticale del layout pila.

  • AbsoluteLayout, che consente di impostare coordinate esatte per i controlli.

  • FlexLayout, che è simile a StackLayout ad eccezione del fatto che consente di eseguire il wrapping dei controlli figlio che contiene se non rientrano in una singola riga o colonna. Questo layout fornisce anche opzioni per l'allineamento e l'adattamento alle diverse dimensioni dello schermo. Ad esempio, un controllo FlexLayout può allineare il controllo figlio a sinistra, a destra o al centro quando è disposto verticalmente. Quando sono allineati orizzontalmente, i controlli possono essere giustificati per garantire una spaziatura uniforme. È possibile utilizzare un FlexLayout orizzontale all'interno di un ScrollView per visualizzare una serie di fotogrammi scorrevoli orizzontalmente (ogni fotogramma potrebbe essere a sua volta un FlexLayout disposto verticalmente):

    Screenshot di un'app in esecuzione con il rendering di FlexLayout sullo schermo. Viene prima eseguito il rendering di un'immagine, poi di un titolo, quindi di un'etichetta di testo e di un pulsante. Tutti questi elementi vengono visualizzati verticalmente all'interno di una casella.

  • Grid, che dispone i controlli in base a una posizione di riga e colonna impostata. È possibile definire le dimensioni di colonna e riga e le relative estensioni, in modo che i layout griglia non abbiano necessariamente un aspetto a scacchiera.

L'immagine seguente riepiloga gli attributi chiave di questi tipi di layout comuni:

Diagramma dei layout più frequentemente usati in un'interfaccia utente di .NET MAUI.

Il layout pila mostra quattro caselle disposte verticalmente. Il layout assoluto mostra quattro caselle disposte sullo schermo esattamente dove specificato dallo sviluppatore. Il layout Flex mostra diverse caselle disposte sullo schermo per sfruttare al meglio l'area dello schermo. Il layout griglia mostra diverse caselle sullo schermo disposte in un motivo a griglia.

Tutti i controlli hanno proprietà. È possibile impostare i valori iniziali di queste proprietà usando XAML (Extensible Application Markup Language). In molti casi è possibile modificare queste proprietà nel codice C# dell'applicazione. Ad esempio, il codice che gestisce l'evento Clicked per il pulsante Click me nell'app .NET MAUI predefinita è simile al seguente:

int count = 0;
private void OnCounterClicked(object sender, EventArgs e)
{
    count+=5;

    if (count == 1)
        CounterBtn.Text = $"Clicked {count} time";
    else
        CounterBtn.Text = $"Clicked {count} times";

    SemanticScreenReader.Announce(CounterBtn.Text);
}

Questo codice modifica la proprietà Text del controllo CounterBtn nella pagina. È anche possibile creare interi layout, pagine e visualizzazioni nel codice, senza usare necessariamente XAML. Si consideri ad esempio la seguente definizione XAML di una pagina:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Phoneword.MainPage">

    <ScrollView>
        <VerticalStackLayout>
            <Label Text="Current count: 0"
                Grid.Row="0"
                FontSize="18"
                FontAttributes="Bold"
                x:Name="CounterLabel"
                HorizontalOptions="Center" />

            <Button Text="Click me"
                Grid.Row="1"
                Clicked="OnCounterClicked"
                HorizontalOptions="Center" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

Il codice equivalente in C# è simile al seguente:

public partial class TestPage : ContentPage
{
    int count = 0;
    
    // Named Label - declared as a member of the class
    Label counterLabel;

    public TestPage()
    {       
        var myScrollView = new ScrollView();

        var myStackLayout = new VerticalStackLayout();
        myScrollView.Content = myStackLayout;

        counterLabel = new Label
        {
            Text = "Current count: 0",
            FontSize = 18,
            FontAttributes = FontAttributes.Bold,
            HorizontalOptions = LayoutOptions.Center
        };
        myStackLayout.Children.Add(counterLabel);
        
        var myButton = new Button
        {
            Text = "Click me",
            HorizontalOptions = LayoutOptions.Center
        };
        myStackLayout.Children.Add(myButton);

        myButton.Clicked += OnCounterClicked;

        this.Content = myScrollView;
    }

    private void OnCounterClicked(object sender, EventArgs e)
    {
        count++;
        counterLabel.Text = $"Current count: {count}";

        SemanticScreenReader.Announce(counterLabel.Text);
    }
}

Il codice C# è più dettagliato, ma offre una maggiore flessibilità che consente di adattare dinamicamente l'interfaccia utente.

Per visualizzare questa pagina all'avvio dell'applicazione, impostare la classe TestPage in AppShell come ShellContent principale:

<ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:TestPage}"
        Route="TestPage" />

Ottimizzazione di un layout

È utile aggiungere un po' di spazio intorno a un controllo. Ogni controllo ha una proprietà Margin che viene rispettata dai layout. Si può pensare al margine come al controllo che distanzia gli altri controlli.

Tutti i layout hanno anche una proprietà Padding che impedisce agli elementi figlio di essere troppo vicini al bordo del layout. Per chiarire questo concetto è possibile immaginare che tutti i controlli siano all'interno di una scatola dotata di pareti imbottite.

Un'altra impostazione utile per creare spazio vuoto è la proprietà Spacing di VerticalStackLayout o HorizontalStackLayout. Imposta lo spazio tra tutti gli elementi figlio del layout. Il valore si aggiunge al margine proprio del controllo, quindi lo spazio vuoto effettivo sarà dato dal margine più la spaziatura.

Verifica delle conoscenze

1.

Quale dei seguenti non è un tipo di layout di .NET MAUI?

2.

Qual è la classe usata per creare una schermata in .NET MAUI?