Creare un'app .NET MAUI
Questa serie di esercitazioni è progettata per illustrare come creare un'app .NET Multipiattaforma (.NET MAUI) che usa solo codice multipiattaforma. Ciò significa che il codice scritto non sarà specifico per Windows, Android, iOS o macOS. L'app che creerai sarà un'app che prende nota, in cui l'utente può creare, salvare e caricare più note.
In questa esercitazione apprenderai a:
- Creare un'app shell MAUI .NET.
- Eseguire l'app nella piattaforma scelta.
- Definire l'interfaccia utente con eXtensible Application Markup Language (XAML) e interagire con gli elementi XAML tramite codice.
- Creare visualizzazioni e associarle ai dati.
- Usare lo spostamento per spostarsi da e verso le pagine.
Si userà Visual Studio 2022 per creare un'applicazione con cui è possibile immettere una nota e salvarla nell'archiviazione del dispositivo. L'applicazione finale è riportata di seguito:
Creare un progetto
Prima di iniziare questa esercitazione, è necessario seguire l'articolo Creare la prima app. Durante la creazione del progetto, usare le impostazioni seguenti:
Nome progetto
L'impostazione deve essere
Notes
. Se il progetto è denominato qualcosa di diverso, il codice copiato e incollato da questa esercitazione può causare errori di compilazione.L'opzione Inserisci soluzione e progetto nella stessa directory
Deselezionare questa impostazione.
Scegliere la versione più recente di .NET Framework durante la creazione del progetto.
Selezionare il dispositivo di destinazione
Le app .NET MAUI sono progettate per essere eseguite in più sistemi operativi e dispositivi. È necessario selezionare la destinazione che si desidera usare per testare ed eseguire il debug dell'app.
Impostare la destinazione di debug nella barra degli strumenti di Visual Studio sul dispositivo con cui si vuole eseguire il debug e il test. I passaggi seguenti illustrano l'impostazione della destinazione di debug su Android:
- Selezionare il pulsante a discesa Debug destinazione .
- Selezionare l'elemento Emulatori Android.
- Selezionare il dispositivo emulatore.
Personalizzare la shell dell'app
Quando Visual Studio crea un progetto MAUI .NET, vengono generati quattro file di codice importanti. Questi elementi sono visibili nel riquadro Esplora soluzioni di Visual Studio:
Questi file consentono di configurare e eseguire l'app MAUI .NET. Ogni file ha uno scopo diverso, descritto di seguito:
MauiProgram.cs
Si tratta di un file di codice che esegue il bootstrap dell'app. Il codice in questo file funge da punto di ingresso multipiattaforma dell'app, che configura e avvia l'app. Il codice di avvio del modello punta alla
App
classe definita dal file App.xaml .App.xaml e App.xaml.cs
Solo per tenere le cose semplici, entrambi questi file sono definiti come un singolo file. Esistono in genere due file con qualsiasi file XAML, il file con estensione xaml stesso e un file di codice corrispondente che ne è un elemento figlio nel Esplora soluzioni. Il file con estensione xaml contiene markup XAML e il file di codice contiene il codice creato dall'utente per interagire con il markup XAML.
Il file App.xaml contiene risorse XAML a livello di app, ad esempio colori, stili o modelli. Il file App.xaml.cs contiene in genere codice che crea un'istanza dell'applicazione Shell. In questo progetto punta alla
AppShell
classe .AppShell.xaml e AppShell.xaml.cs
Questo file definisce la classe , usata per definire la
AppShell
gerarchia visiva dell'app.MainPage.xaml e MainPage.xaml.cs
Questa è la pagina di avvio visualizzata dall'app. Il file MainPage.xaml definisce l'interfaccia utente (interfaccia utente) della pagina. MainPage.xaml.cs contiene il code-behind per XAML, ad esempio il codice per un evento click del pulsante.
Aggiungere una pagina "about"
La prima personalizzazione da eseguire consiste nell'aggiungere un'altra pagina al progetto. Questa pagina è una pagina "about", che rappresenta informazioni su questa app, ad esempio l'autore, la versione e forse un collegamento per altre informazioni.
Nel riquadro Esplora soluzioni di Visual Studio fare clic con il pulsante destro del mouse sul progetto> Note Aggiungi>nuovo elemento....
Nella finestra di dialogo Aggiungi nuovo elemento selezionare .NET MAUI nell'elenco dei modelli sul lato sinistro della finestra. Selezionare quindi il modello ContentPage (XAML) di .NET MAUI. Assegnare al file il nome AboutPage.xaml e quindi selezionare Aggiungi.
Il file AboutPage.xaml aprirà una nuova scheda del documento, visualizzando tutto il markup XAML che rappresenta l'interfaccia utente della pagina. Sostituire il markup XAML con il markup seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.AboutPage"> <VerticalStackLayout Spacing="10" Margin="10"> <HorizontalStackLayout Spacing="10"> <Image Source="dotnet_bot.png" SemanticProperties.Description="The dot net bot waving hello!" HeightRequest="64" /> <Label FontSize="22" FontAttributes="Bold" Text="Notes" VerticalOptions="End" /> <Label FontSize="22" Text="v1.0" VerticalOptions="End" /> </HorizontalStackLayout> <Label Text="This app is written in XAML and C# with .NET MAUI." /> <Button Text="Learn more..." Clicked="LearnMore_Clicked" /> </VerticalStackLayout> </ContentPage>
Salvare il file premendo CTRL+S o selezionando il menu File>Salva AboutPage.xaml.
Suddividere le parti principali dei controlli XAML presenti nella pagina:
<ContentPage>
è l'oggetto radice per laAboutPage
classe .<VerticalStackLayout>
è l'unico oggetto figlio dell'oggetto ContentPage. ContentPage può avere un solo oggetto figlio. Il VerticalStackLayout tipo può avere più elementi figlio. Questo controllo di layout dispone verticalmente gli elementi figlio, uno dopo l'altro.<HorizontalStackLayout>
opera come ,<VerticalStackLayout>
ad eccezione dei relativi elementi figlio sono disposti orizzontalmente.<Image>
visualizza un'immagine, in questo caso usa l'immaginedotnet_bot.png
fornita con ogni progetto MAUI .NET.Importante
Il file aggiunto al progetto è effettivamente
dotnet_bot.svg
. .NET MAUI converte i file SVG (Scalable Vector Graphics) in file PNG (Portable Network Graphic) basati sul dispositivo di destinazione. Pertanto, quando si aggiunge un file SVG al progetto di app MAUI .NET, deve essere fatto riferimento da XAML o C# con un'estensione.png
. L'unico riferimento al file SVG deve essere nel file di progetto.<Label>
controlla il testo da visualizzare.<Button>
i controlli possono essere premuti dall'utente, che generano l'eventoClicked
. È possibile eseguire il codice in risposta all'eventoClicked
.Clicked="LearnMore_Clicked"
L'evento
Clicked
del pulsante viene assegnato alLearnMore_Clicked
gestore eventi, che verrà definito nel file code-behind. Questo codice verrà creato nel passaggio successivo.
Gestire l'evento Clicked
Il passaggio successivo consiste nell'aggiungere il codice per l'evento Clicked
del pulsante.
Nel riquadro Esplora soluzioni di Visual Studio espandere il file AboutPage.xaml per visualizzare il file code-behind AboutPage.xaml.cs. Fare quindi doppio clic sul file AboutPage.xaml.cs per aprirlo nell'editor di codice.
Aggiungere il codice del gestore eventi seguente
LearnMore_Clicked
, che apre il browser di sistema a un URL specifico:private async void LearnMore_Clicked(object sender, EventArgs e) { // Navigate to the specified URL in the system browser. await Launcher.Default.OpenAsync("https://aka.ms/maui"); }
Si noti che la
async
parola chiave è stata aggiunta alla dichiarazione del metodo, che consente l'uso dellaawait
parola chiave all'apertura del browser di sistema.Salvare il file premendo CTRL+S o selezionando il menu File>Salva AboutPage.xaml.cs.
Ora che il codice XAML e il code-behind di AboutPage
è completo, è necessario visualizzarlo nell'app.
Aggiungere risorse immagine
Alcuni controlli possono usare immagini che migliorano l'interazione degli utenti con l'app. In questa sezione verranno scaricate due immagini che verranno usate nell'app, insieme a due immagini alternative da usare con iOS.
Scaricare le immagini seguenti:
Icona: Informazioni su
Questa immagine viene usata come icona per la pagina about creata in precedenza.Icona: Note
Questa immagine viene usata come icona per la pagina delle note che verrà creata nella parte successiva di questa esercitazione.
Dopo aver scaricato le immagini, è possibile spostarle con Esplora file nella cartella Resources\Images del progetto. Qualsiasi file in questa cartella viene incluso automaticamente nel progetto come risorsa MauiImage . È anche possibile usare Visual Studio per aggiungere le immagini al progetto. Se si spostano le immagini a mano, ignorare la procedura seguente.
Importante
Non ignorare il download delle immagini specifiche di iOS, è necessario completare questa esercitazione.
Spostare le immagini con Visual Studio
Nel riquadro Esplora soluzioni di Visual Studio, espandere la cartella Risorse, che contiene la cartella Immagini.
Suggerimento
È possibile usare Esplora file per trascinare le immagini direttamente nel riquadro Esplora soluzioni, nella parte superiore della cartella Immagini. In questo modo i file vengono spostati automaticamente nella cartella e li include nel progetto. Se si sceglie di trascinare i file, ignorare il resto di questa procedura.
Fare clic con il pulsante destro del mouse su Immagini, quindi selezionare Aggiungi>Elemento esistente....
Passare alla cartella che contiene le immagini scaricate.
Modificare il filtro passando dal filtro del tipo di file a File di immagine.
Tenere premuto CTRL e fare clic su ognuna delle immagini scaricate, quindi premere Aggiungi
Modificare la shell dell'app
Come indicato all'inizio di questo articolo, la classe definisce la AppShell
gerarchia visiva di un'app, il markup XAML usato per creare l'interfaccia utente dell'app. Aggiornare il codice XAML per aggiungere un TabBar controllo:
Fare doppio clic sul file AppShell.xaml nel riquadro Esplora soluzioni per aprire l'editor XAML. Sostituire il markup XAML con il codice seguente:
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="Notes.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Notes" Shell.FlyoutBehavior="Disabled"> <TabBar> <ShellContent Title="Notes" ContentTemplate="{DataTemplate local:MainPage}" Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" /> <ShellContent Title="About" ContentTemplate="{DataTemplate local:AboutPage}" Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" /> </TabBar> </Shell>
Salvare il file premendo CTRL+S o selezionando il menu File>Salva AppShell.xaml.
Suddividere le parti chiave del codice XAML:
<Shell>
è l'oggetto radice del markup XAML.<TabBar>
è il contenuto di Shell.- Due
<ShellContent>
oggetti all'interno di<TabBar>
. Prima di sostituire il codice del modello, è presente un singolo<ShellContent>
oggetto, che punta allaMainPage
pagina.
Gli TabBar
elementi figlio e non rappresentano elementi dell'interfaccia utente, ma piuttosto l'organizzazione della gerarchia visiva dell'app. Shell accetta questi oggetti e produce l'interfaccia utente per il contenuto, con una barra nella parte superiore che rappresenta ogni pagina. La ShellContent.Icon
proprietà per ogni pagina usa una sintassi speciale: {OnPlatform ...}
. Questa sintassi viene elaborata quando le pagine XAML vengono compilate per ogni piattaforma e con esso è possibile specificare un valore di proprietà per ogni piattaforma. In questo caso, ogni piattaforma usa l'icona icon_about.png
per impostazione predefinita, ma iOS e MacCatalyst useranno icon_about_ios.png
.
Ogni <ShellContent>
oggetto punta a una pagina da visualizzare. Questa proprietà viene impostata dalla ContentTemplate
proprietà .
Eseguire l'app
Eseguire l'app premendo F5 o premendo il pulsante di riproduzione nella parte superiore di Visual Studio:
Si noterà che sono presenti due schede: Note e Informazioni. Premere la scheda Informazioni e l'app passa all'oggetto AboutPage
creato. Premere il pulsante Altre informazioni per aprire il Web browser.
Chiudere l'app e tornare a Visual Studio. Se si usa l'emulatore Android, terminare l'app nel dispositivo virtuale o premere il pulsante di arresto nella parte superiore di Visual Studio:
Creare una pagina per una nota
Ora che l'app contiene MainPage
e AboutPage
, è possibile iniziare a creare il resto dell'app. Prima di tutto, si creerà una pagina che consente a un utente di creare e visualizzare la nota, quindi si scriverà il codice per caricare e salvare la nota.
La pagina della nota visualizzerà la nota e consentirà di salvarla o eliminarla. Aggiungere prima di tutto la nuova pagina al progetto:
Nel riquadro Esplora soluzioni di Visual Studio fare clic con il pulsante destro del mouse sul progetto> Note Aggiungi>nuovo elemento....
Nella finestra di dialogo Aggiungi nuovo elemento selezionare .NET MAUI nell'elenco dei modelli sul lato sinistro della finestra. Selezionare quindi il modello ContentPage (XAML) di .NET MAUI. Assegnare al file il nome NotePage.xaml e quindi selezionare Aggiungi.
Il file NotePage.xaml verrà aperto in una nuova scheda, visualizzando tutto il markup XAML che rappresenta l'interfaccia utente della pagina. Sostituire il markup del codice XAML nel markup seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.NotePage" Title="Note"> <VerticalStackLayout Spacing="10" Margin="5"> <Editor x:Name="TextEditor" Placeholder="Enter your note" HeightRequest="100" /> <Grid ColumnDefinitions="*,*" ColumnSpacing="4"> <Button Text="Save" Clicked="SaveButton_Clicked" /> <Button Grid.Column="1" Text="Delete" Clicked="DeleteButton_Clicked" /> </Grid> </VerticalStackLayout> </ContentPage>
Salvare il file premendo CTRL+S o selezionando il menu File>Salva NotePage.xaml.
Suddividere le parti principali dei controlli XAML presenti nella pagina:
<VerticalStackLayout>
dispone i controlli figlio verticalmente, uno sotto l'altro.<Editor>
è un controllo editor di testo a più righe ed è il primo controllo all'interno di VerticalStackLayout.<Grid>
è un controllo di layout ed è il secondo controllo all'interno di VerticalStackLayout.Questo controllo definisce colonne e righe da creare celle. I controlli figlio vengono posizionati all'interno di tali celle.
Per impostazione predefinita, il Grid controllo contiene una singola riga e colonna, creando una singola cella. Le colonne vengono definite con una larghezza e il
*
valore per width indica alla colonna di riempire il maggior numero possibile di spazio. Il frammento di codice precedente ha definito due colonne, che usano il maggior numero di spazio possibile, che distribuisce uniformemente le colonne nello spazio allocato:ColumnDefinitions="*,*"
. Le dimensioni delle colonne sono separate da un,
carattere.Le colonne e le righe definite da un Grid oggetto vengono indicizzate a partire da 0. La prima colonna sarà quindi indice 0, la seconda colonna è indice 1 e così via.
Due
<Button>
controlli si trovano all'interno di<Grid>
e hanno assegnato una colonna. Se un controllo figlio non definisce un'assegnazione di colonna, viene automaticamente assegnato alla prima colonna. In questo markup, il primo pulsante è il pulsante "Salva" e assegnato automaticamente alla prima colonna, colonna 0. Il secondo pulsante è il pulsante "Elimina" e assegnato alla seconda colonna, colonna 1.Si noti che i due pulsanti hanno l'evento
Clicked
gestito. Si aggiungerà il codice per tali gestori nella sezione successiva.
Caricare e salvare una nota
Aprire il file code-behind NotePage.xaml.cs . È possibile aprire il code-behind per il file NotePage.xaml in tre modi:
- Se NotePage.xaml è aperto ed è il documento attivo da modificare, premere F7.
- Se NotePage.xaml è aperto ed è il documento attivo da modificare, fare clic con il pulsante destro del mouse nell'editor di testo e selezionare Visualizza codice.
- Usa il Esplora soluzioni per espandere la voce NotePage.xaml, rivelando il file NotePage.xaml.cs. Fare doppio clic sul file per aprirlo.
Quando si aggiunge un nuovo file XAML, il code-behind contiene una singola riga nel costruttore, una chiamata al InitializeComponent
metodo :
namespace Notes;
public partial class NotePage : ContentPage
{
public NotePage()
{
InitializeComponent();
}
}
Il InitializeComponent
metodo legge il markup XAML e inizializza tutti gli oggetti definiti dal markup. Gli oggetti sono connessi nelle relazioni padre-figlio e i gestori eventi definiti nel codice vengono associati agli eventi impostati in XAML.
Dopo aver compreso un po' di più sui file code-behind, si aggiungerà codice al file code-behind NotePage.xaml.cs per gestire il caricamento e il salvataggio delle note.
Quando viene creata una nota, viene salvata nel dispositivo come file di testo. Il nome del file è rappresentato dalla
_fileName
variabile . Aggiungere la dichiarazione di variabile seguentestring
allaNotePage
classe :public partial class NotePage : ContentPage { string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
Il codice precedente crea un percorso al file, archiviandolo nella directory dei dati locali dell'app. Il nome del file è notes.txt.
Nel costruttore della classe, dopo aver chiamato il
InitializeComponent
metodo , leggere il file dal dispositivo e archiviarne il contenuto nellaTextEditor
proprietà delText
controllo:public NotePage() { InitializeComponent(); if (File.Exists(_fileName)) TextEditor.Text = File.ReadAllText(_fileName); }
Aggiungere quindi il codice per gestire gli
Clicked
eventi definiti nel codice XAML:private void SaveButton_Clicked(object sender, EventArgs e) { // Save the file. File.WriteAllText(_fileName, TextEditor.Text); } private void DeleteButton_Clicked(object sender, EventArgs e) { // Delete the file. if (File.Exists(_fileName)) File.Delete(_fileName); TextEditor.Text = string.Empty; }
Il
SaveButton_Clicked
metodo scrive il testo nel Editor controllo nel file rappresentato dalla_fileName
variabile .Il
DeleteButton_Clicked
metodo controlla innanzitutto se il file rappresentato dalla_fileName
variabile e, se esistente, lo elimina. Successivamente, il Editor testo del controllo viene cancellato.Salvare il file premendo CTRL+S o selezionando il menu File>Save NotePage.xaml.cs.
Il codice finale per il file code-behind dovrebbe essere simile al seguente:
namespace Notes;
public partial class NotePage : ContentPage
{
string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
public NotePage()
{
InitializeComponent();
if (File.Exists(_fileName))
TextEditor.Text = File.ReadAllText(_fileName);
}
private void SaveButton_Clicked(object sender, EventArgs e)
{
// Save the file.
File.WriteAllText(_fileName, TextEditor.Text);
}
private void DeleteButton_Clicked(object sender, EventArgs e)
{
// Delete the file.
if (File.Exists(_fileName))
File.Delete(_fileName);
TextEditor.Text = string.Empty;
}
}
Testare la nota
Ora che la pagina della nota è stata completata, è necessario un modo per presentarla all'utente. Aprire il file AppShell.xaml e modificare la prima ShellContent voce in modo che punti a NotePage
invece di MainPage
:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Notes"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate local:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
Salvare il file ed eseguire l'app. Provare a digitare nella casella di immissione e premere il pulsante Salva . Chiudere l'app e riaprirla. La nota immessa deve essere caricata dalla risorsa di archiviazione del dispositivo.
Associare i dati all'interfaccia utente e spostarsi nelle pagine
Questa parte dell'esercitazione presenta i concetti relativi a visualizzazioni, modelli e navigazione in-app.
Nei passaggi precedenti dell'esercitazione sono state aggiunte due pagine al progetto: NotePage
e AboutPage
. Le pagine rappresentano una visualizzazione dei dati. NotePage
è una "visualizzazione" che visualizza i "dati delle note" e AboutPage
è una "visualizzazione" che visualizza "dati delle informazioni sull'app". Entrambe queste viste hanno un modello di dati hardcoded o incorporati in esse e sarà necessario separare il modello di dati dalla vista.
Qual è il vantaggio della separazione del modello dalla vista? Consente di progettare la visualizzazione per rappresentare e interagire con qualsiasi parte del modello senza preoccuparsi del codice effettivo che implementa il modello. Questa operazione viene eseguita usando il data binding, un elemento che verrà presentato più avanti in questa esercitazione. Per il momento, però, ristruttura il progetto.
Separare la visualizzazione e il modello
Effettuare il refactoring del codice esistente per separare il modello dalla vista. I passaggi successivi organizzano il codice in modo che le visualizzazioni e i modelli vengano definiti separatamente l'uno dall'altro.
Eliminare MainPage.xaml e MainPage.xaml.cs dal progetto in quanto non sono più necessari. Nel riquadro Esplora soluzioni individuare la voce MainPage.xaml, fare clic con il pulsante destro del mouse e selezionare Elimina.
Suggerimento
Anche l'eliminazione dell'elemento MainPage.xaml deve eliminare anche l'elemento MainPage.xaml.cs . Se MainPage.xaml.cs non è stato eliminato, fare clic con il pulsante destro del mouse su di esso e selezionare Elimina.
Fare clic con il pulsante destro del mouse sul Notes progetto e scegliere Aggiungi>nuova cartella. Denominare la cartella Models.
Fare clic con il pulsante destro del mouse sul Notes progetto e scegliere Aggiungi>nuova cartella. Denominare la cartella Views.
Trovare l'elemento NotePage.xaml e trascinarlo nella Views cartella . Il NotePage.xaml.cs deve spostarsi con esso.
Importante
Quando si sposta un file, Visual Studio richiede in genere un avviso su come l'operazione di spostamento potrebbe richiedere molto tempo. Questo non dovrebbe essere un problema qui, premere OK se viene visualizzato questo avviso.
Visual Studio può anche chiedere se si vuole modificare lo spazio dei nomi del file spostato. Selezionare No come i passaggi successivi modificheranno lo spazio dei nomi.
Trovare l'elemento AboutPage.xaml e trascinarlo nella Views cartella . Il AboutPage.xaml.cs deve spostarsi con esso.
Aggiornare lo spazio dei nomi della visualizzazione
Ora che le visualizzazioni sono state spostate nella Views cartella, è necessario aggiornare gli spazi dei nomi in modo che corrispondano. Lo spazio dei nomi per i file XAML e code-behind delle pagine è impostato su Notes
. Questa operazione deve essere aggiornata a Notes.Views
.
Nel riquadro Esplora soluzioni espandere Sia NotePage.xaml che AboutPage.xaml per visualizzare i file code-behind:
Fare doppio clic sull'elemento NotePage.xaml.cs per aprire l'editor di codice. Modificare lo spazio dei nomi in
Notes.Views
:namespace Notes.Views;
Ripetere i passaggi precedenti per l'elemento AboutPage.xaml.cs .
Fare doppio clic sull'elemento NotePage.xaml per aprire l'editor XAML. Viene fatto riferimento allo spazio dei nomi precedente tramite l'attributo
x:Class
, che definisce quale tipo di classe è il code-behind per XAML. Questa voce non è solo lo spazio dei nomi, ma lo spazio dei nomi con il tipo . Modificare il valorex:Class
inNotes.Views.NotePage
:x:Class="Notes.Views.NotePage"
Ripetere il passaggio precedente per l'elemento AboutPage.xaml , ma impostare il
x:Class
valore suNotes.Views.AboutPage
.
Correggere il riferimento allo spazio dei nomi in Shell
AppShell.xaml definisce due schede, una per NotesPage
e un'altra per AboutPage
. Ora che queste due pagine sono state spostate in un nuovo spazio dei nomi, il mapping dei tipi nel codice XAML non è valido. Nel riquadro Esplora soluzioni fare doppio clic sulla voce AppShell.xaml per aprirla nell'editor XAML. Dovrebbe essere simile al frammento di codice seguente:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Notes"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate local:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
Uno spazio dei nomi .NET viene importato nel codice XAML tramite una dichiarazione dello spazio dei nomi XML. Nel markup XAML precedente, si tratta dell'attributo xmlns:local="clr-namespace:Notes"
nell'elemento radice: <Shell>
. Il formato di dichiarazione di uno spazio dei nomi XML per importare uno spazio dei nomi .NET nello stesso assembly è:
xmlns:{XML namespace name}="clr-namespace:{.NET namespace}"
La dichiarazione precedente esegue quindi il mapping dello spazio dei nomi XML di local
allo spazio dei nomi .NET di Notes
. È pratica comune eseguire il mapping del nome local
allo spazio dei nomi radice del progetto.
Rimuovere lo spazio dei local
nomi XML e aggiungerne uno nuovo. Questo nuovo spazio dei nomi XML verrà mappato allo spazio dei nomi .NET di Notes.Views
, quindi denominarlo views
. La dichiarazione dovrebbe essere simile all'attributo seguente: xmlns:views="clr-namespace:Notes.Views"
.
Lo local
spazio dei nomi XML è stato usato dalle ShellContent.ContentTemplate
proprietà e modificarlo in views
. Il codice XAML dovrebbe ora essere simile al frammento di codice seguente:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Notes.Views"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate views:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate views:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
Dovrebbe ora essere possibile eseguire l'app senza errori del compilatore e tutto dovrebbe funzionare come in precedenza.
Definire il modello
Attualmente il modello è costituito dai dati incorporati nella nota e sulle visualizzazioni. Verranno create nuove classi per rappresentare tali dati. Prima di tutto, il modello per rappresentare i dati della pagina di una nota:
Nel riquadro Esplora soluzioni fare clic con il pulsante destro del mouse sulla Models cartella e scegliere Aggiungi>classe....
Denominare la classe Note.cs e premere Aggiungi.
Aprire Note.cs e sostituire il codice con il frammento di codice seguente:
namespace Notes.Models; internal class Note { public string Filename { get; set; } public string Text { get; set; } public DateTime Date { get; set; } }
Salvare il file.
Creare quindi il modello della pagina about:
Nel riquadro Esplora soluzioni fare clic con il pulsante destro del mouse sulla Models cartella e scegliere Aggiungi>classe....
Denominare la classe About.cs e premere Aggiungi.
Aprire About.cs e sostituire il codice con il frammento di codice seguente:
namespace Notes.Models; internal class About { public string Title => AppInfo.Name; public string Version => AppInfo.VersionString; public string MoreInfoUrl => "https://aka.ms/maui"; public string Message => "This app is written in XAML and C# with .NET MAUI."; }
Salvare il file.
Pagina Aggiorna informazioni
La pagina about sarà la pagina più rapida da aggiornare e sarà possibile eseguire l'app e vedere come carica i dati dal modello.
Nel riquadro Esplora soluzioni aprire il file Views\AboutPage.xaml.
Sostituire il contenuto con il frammento di codice seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:models="clr-namespace:Notes.Models" x:Class="Notes.Views.AboutPage"> <ContentPage.BindingContext> <models:About /> </ContentPage.BindingContext> <VerticalStackLayout Spacing="10" Margin="10"> <HorizontalStackLayout Spacing="10"> <Image Source="dotnet_bot.png" SemanticProperties.Description="The dot net bot waving hello!" HeightRequest="64" /> <Label FontSize="22" FontAttributes="Bold" Text="{Binding Title}" VerticalOptions="End" /> <Label FontSize="22" Text="{Binding Version}" VerticalOptions="End" /> </HorizontalStackLayout> <Label Text="{Binding Message}" /> <Button Text="Learn more..." Clicked="LearnMore_Clicked" /> </VerticalStackLayout> </ContentPage>
Esaminiamo le righe modificate, evidenziate nel frammento precedente:
xmlns:models="clr-namespace:Notes.Models"
Questa riga esegue il mapping dello
Notes.Models
spazio dei nomi .NET allo spazio deimodels
nomi XML.La
BindingContext
proprietà di ContentPage è impostata su un'istanza dellaNote.Models.About
classe utilizzando lo spazio dei nomi XML e l'oggetto dimodels:About
. È stato impostato utilizzando la sintassi dell'elemento proprietà anziché un attributo XML.Importante
Fino ad ora, le proprietà sono state impostate usando un attributo XML. Questa operazione è ideale per i valori semplici, ad esempio una
Label.FontSize
proprietà . Tuttavia, se il valore della proprietà è più complesso, è necessario usare la sintassi degli elementi di proprietà per creare l'oggetto. Si consideri l'esempio seguente di creazione di un'etichetta con il relativoFontSize
set di proprietà:<Label FontSize="22" />
La stessa
FontSize
proprietà può essere impostata usando la sintassi degli elementi di proprietà:<Label> <Label.FontSize> 22 </Label.FontSize> </Label>
Tre
<Label>
controlli avevano ilText
valore della proprietà modificato da una stringa hardcoded alla sintassi di associazione:{Binding PATH}
.{Binding}
la sintassi viene elaborata in fase di esecuzione, consentendo la dinamica del valore restituito dall'associazione. LaPATH
parte di è il percorso della{Binding PATH}
proprietà a cui eseguire l'associazione. La proprietà deriva dall'oggetto delBindingContext
controllo corrente. Con il<Label>
controllo ,BindingContext
non è impostato. Il contesto viene ereditato dall'elemento padre quando non viene impostato dal controllo , che in questo caso l'impostazione dell'oggetto padre è l'oggetto radice: ContentPage.L'oggetto in è un'istanza
BindingContext
delAbout
modello. Il percorso di associazione di una delle etichette associa laLabel.Text
proprietà allaAbout.Title
proprietà .
La modifica finale alla pagina about sta aggiornando il pulsante che apre una pagina Web. L'URL è stato hardcoded nel code-behind, ma l'URL deve provenire dal modello presente nella BindingContext
proprietà .
Nel riquadro Esplora soluzioni aprire il file Views\AboutPage.xaml.cs.
Sostituire il metodo
LearnMore_Clicked
con il codice seguente:private async void LearnMore_Clicked(object sender, EventArgs e) { if (BindingContext is Models.About about) { // Navigate to the specified URL in the system browser. await Launcher.Default.OpenAsync(about.MoreInfoUrl); } }
Se si esamina la riga evidenziata, il codice controlla se BindingContext
è un Models.About
tipo e, in caso affermativo, lo assegna alla about
variabile. La riga successiva all'interno dell'istruzione if
apre il browser all'URL fornito dalla about.MoreInfoUrl
proprietà .
Eseguire l'app e si noterà che viene eseguita esattamente come in precedenza. Provare a modificare i valori del modello e vedere come cambiano anche l'interfaccia utente e l'URL aperti dal browser.
Pagina Aggiorna nota
La sezione precedente ha associato la about visualizzazione pagina al about modello e ora si eseguirà la stessa operazione, associando la note visualizzazione al note modello. In questo caso, tuttavia, il modello non verrà creato in XAML, ma verrà fornito nel code-behind nei passaggi successivi.
Nel riquadro Esplora soluzioni aprire il file Views\NotePage.xaml.
Modificare il
<Editor>
controllo aggiungendo laText
proprietà . Associare la proprietà allaText
proprietà :<Editor ... Text="{Binding Text}"
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.Views.NotePage" Title="Note"> <VerticalStackLayout Spacing="10" Margin="5"> <Editor x:Name="TextEditor" Placeholder="Enter your note" Text="{Binding Text}" HeightRequest="100" /> <Grid ColumnDefinitions="*,*" ColumnSpacing="4"> <Button Text="Save" Clicked="SaveButton_Clicked" /> <Button Grid.Column="1" Text="Delete" Clicked="DeleteButton_Clicked" /> </Grid> </VerticalStackLayout> </ContentPage>
Le modifiche per il code-behind sono più complesse del codice XAML. Il codice corrente sta caricando il contenuto del file nel costruttore e quindi impostandolo direttamente sulla TextEditor.Text
proprietà . Di seguito è riportato l'aspetto del codice corrente:
public NotePage()
{
InitializeComponent();
if (File.Exists(_fileName))
TextEditor.Text = File.ReadAllText(_fileName);
}
Anziché caricare la nota nel costruttore, creare un nuovo LoadNote
metodo. Questo metodo eseguirà le operazioni seguenti:
- Accettare un parametro nome file.
- Creare un nuovo modello di nota e impostare il nome del file.
- Se il file esiste, caricarne il contenuto nel modello.
- Se il file esiste, aggiornare il modello con la data di creazione del file.
- Impostare la
BindingContext
proprietà della pagina sul modello.
Nel riquadro Esplora soluzioni aprire il file Views\NotePage.xaml.cs.
Aggiungere il metodo seguente alla classe :
private void LoadNote(string fileName) { Models.Note noteModel = new Models.Note(); noteModel.Filename = fileName; if (File.Exists(fileName)) { noteModel.Date = File.GetCreationTime(fileName); noteModel.Text = File.ReadAllText(fileName); } BindingContext = noteModel; }
Aggiornare il costruttore della classe per chiamare
LoadNote
. Il nome del file per la nota deve essere un nome generato in modo casuale da creare nella directory dei dati locali dell'app.public NotePage() { InitializeComponent(); string appDataPath = FileSystem.AppDataDirectory; string randomFileName = $"{Path.GetRandomFileName()}.notes.txt"; LoadNote(Path.Combine(appDataPath, randomFileName)); }
Aggiungere una visualizzazione e un modello che elenca tutte le note
Questa parte dell'esercitazione aggiunge la parte finale dell'app, una visualizzazione che visualizza tutte le note create in precedenza.
Più note e navigazione
Attualmente la visualizzazione note visualizza una singola nota. Per visualizzare più note, creare una nuova visualizzazione e un nuovo modello: AllNotes.
- Nel riquadro Esplora soluzioni fare clic con il pulsante destro del mouse sulla Views cartella e scegliere Aggiungi>nuovo elemento...
- Nella finestra di dialogo Aggiungi nuovo elemento selezionare .NET MAUI nell'elenco dei modelli sul lato sinistro della finestra. Selezionare quindi il modello ContentPage (XAML) di .NET MAUI. Assegnare al file il nome AllNotesPage.xaml e quindi selezionare Aggiungi.
- Nel riquadro Esplora soluzioni fare clic con il pulsante destro del mouse sulla Models cartella e scegliere Aggiungi>classe...
- Assegnare alla classe il nome AllNotes.cs e premere Aggiungi.
Codificare il modello AllNotes
Il nuovo modello rappresenterà i dati necessari per visualizzare più note. Questi dati saranno una proprietà che rappresenta una raccolta di note. La raccolta sarà un oggetto ObservableCollection
che è una raccolta specializzata. Quando un controllo che elenca più elementi, ad esempio , ListViewè associato a un ObservableCollection
, i due interagiscono per mantenere automaticamente sincronizzato l'elenco di elementi con la raccolta. Se l'elenco aggiunge un elemento, la raccolta viene aggiornata. Se la raccolta aggiunge un elemento, il controllo viene aggiornato automaticamente con un nuovo elemento.
Nel riquadro Esplora soluzioni aprire il file Models\AllNotes.cs.
Sostituire il codice con il frammento di codice seguente:
using System.Collections.ObjectModel; namespace Notes.Models; internal class AllNotes { public ObservableCollection<Note> Notes { get; set; } = new ObservableCollection<Note>(); public AllNotes() => LoadNotes(); public void LoadNotes() { Notes.Clear(); // Get the folder where the notes are stored. string appDataPath = FileSystem.AppDataDirectory; // Use Linq extensions to load the *.notes.txt files. IEnumerable<Note> notes = Directory // Select the file names from the directory .EnumerateFiles(appDataPath, "*.notes.txt") // Each file name is used to create a new Note .Select(filename => new Note() { Filename = filename, Text = File.ReadAllText(filename), Date = File.GetLastWriteTime(filename) }) // With the final collection of notes, order them by date .OrderBy(note => note.Date); // Add each note into the ObservableCollection foreach (Note note in notes) Notes.Add(note); } }
Il codice precedente dichiara una raccolta, denominata Notes
e usa il LoadNotes
metodo per caricare note dal dispositivo. Questo metodo usa le estensioni LINQ per caricare, trasformare e ordinare i dati nella Notes
raccolta.
Progettare la pagina AllNotes
Successivamente, la visualizzazione deve essere progettata per supportare il modello AllNotes .
Nel riquadro Esplora soluzioni aprire il file Views\AllNotesPage.xaml.
Sostituire il codice con il markup seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.Views.AllNotesPage" Title="Your Notes"> <!-- Add an item to the toolbar --> <ContentPage.ToolbarItems> <ToolbarItem Text="Add" Clicked="Add_Clicked" IconImageSource="{FontImage Glyph='+', Color=Black, Size=22}" /> </ContentPage.ToolbarItems> <!-- Display notes in a list --> <CollectionView x:Name="notesCollection" ItemsSource="{Binding Notes}" Margin="20" SelectionMode="Single" SelectionChanged="notesCollection_SelectionChanged"> <!-- Designate how the collection of items are laid out --> <CollectionView.ItemsLayout> <LinearItemsLayout Orientation="Vertical" ItemSpacing="10" /> </CollectionView.ItemsLayout> <!-- Define the appearance of each item in the list --> <CollectionView.ItemTemplate> <DataTemplate> <StackLayout> <Label Text="{Binding Text}" FontSize="22"/> <Label Text="{Binding Date}" FontSize="14" TextColor="Silver"/> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </ContentPage>
Il codice XAML precedente introduce alcuni nuovi concetti:
La
ContentPage.ToolbarItems
proprietà contiene un oggettoToolbarItem
. I pulsanti definiti qui vengono in genere visualizzati nella parte superiore dell'app, lungo il titolo della pagina. A seconda della piattaforma, tuttavia, potrebbe trovarsi in una posizione diversa. Quando si preme uno di questi pulsanti, viene generato l'eventoClicked
, proprio come un pulsante normale.La
ToolbarItem.IconImageSource
proprietà imposta l'icona da visualizzare sul pulsante. L'icona può essere qualsiasi risorsa immagine definita dal progetto, tuttavia, in questo esempio viene usato un oggettoFontImage
. UnFontImage
oggetto può utilizzare un singolo glifo da un tipo di carattere come immagine.Il CollectionView controllo visualizza una raccolta di elementi e, in questo caso, è associato alla proprietà del
Notes
modello. Il modo in cui ogni elemento viene presentato dalla visualizzazione raccolta viene impostato tramite leCollectionView.ItemsLayout
proprietà eCollectionView.ItemTemplate
.Per ogni elemento della raccolta, genera
CollectionView.ItemTemplate
il codice XAML dichiarato. DiBindingContext
questo codice XAML diventa l'elemento della raccolta stesso, in questo caso ogni singola nota. Il modello per la nota usa due etichette, associate alle proprietà eDate
dellaText
nota.CollectionView Gestisce l'evento
SelectionChanged
, generato quando viene selezionato un elemento nella visualizzazione raccolta.
Il code-behind per la visualizzazione deve essere scritto per caricare le note e gestire gli eventi.
Nel riquadro Esplora soluzioni aprire il file Views/AllNotesPage.xaml.cs.
Sostituire il codice con il frammento di codice seguente:
namespace Notes.Views; public partial class AllNotesPage : ContentPage { public AllNotesPage() { InitializeComponent(); BindingContext = new Models.AllNotes(); } protected override void OnAppearing() { ((Models.AllNotes)BindingContext).LoadNotes(); } private async void Add_Clicked(object sender, EventArgs e) { await Shell.Current.GoToAsync(nameof(NotePage)); } private async void notesCollection_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection.Count != 0) { // Get the note model var note = (Models.Note)e.CurrentSelection[0]; // Should navigate to "NotePage?ItemId=path\on\device\XYZ.notes.txt" await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.Filename}"); // Unselect the UI notesCollection.SelectedItem = null; } } }
Questo codice usa il costruttore per impostare l'oggetto BindingContext
della pagina sul modello.
Il OnAppearing
metodo viene sottoposto a override dalla classe base. Questo metodo viene chiamato automaticamente ogni volta che viene visualizzata la pagina, ad esempio quando si passa alla pagina. Il codice qui indica al modello di caricare le note. Poiché nella CollectionView visualizzazione AllNotes è associato alla proprietà del Notes
modello AllNotes, che è un oggetto ObservableCollection
, ogni volta che vengono caricate le note, l'oggetto CollectionView viene aggiornato automaticamente.
Il Add_Clicked
gestore introduce un altro nuovo concetto, la navigazione. Poiché l'app usa la shell MAUI .NET, è possibile passare alle pagine chiamando il Shell.Current.GoToAsync
metodo . Si noti che il gestore viene dichiarato con la async
parola chiave , che consente l'uso della parola chiave durante lo await
spostamento. Questo gestore passa a NotePage
.
L'ultima parte di codice nel frammento precedente è il notesCollection_SelectionChanged
gestore. Questo metodo accetta l'elemento attualmente selezionato, un Note modello e usa le relative informazioni per passare a NotePage
. GoToAsync usa una stringa URI per lo spostamento. In questo caso, viene costruita una stringa che usa un parametro della stringa di query per impostare una proprietà nella pagina di destinazione. La stringa interpolata che rappresenta l'URI finisce per essere simile alla stringa seguente:
NotePage?ItemId=path\on\device\XYZ.notes.txt
Il ItemId=
parametro è impostato sul nome del file nel dispositivo in cui è archiviata la nota.
Visual Studio potrebbe indicare che la NotePage.ItemId
proprietà non esiste, che non esiste. Il passaggio successivo consiste nel modificare la Note visualizzazione per caricare il modello in base al ItemId
parametro che verrà creato.
Parametri della stringa di query
La Note vista deve supportare il parametro della stringa di query, ItemId
. Crearlo ora:
Nel riquadro Esplora soluzioni aprire il file Views/NotePage.xaml.cs.
Aggiungere l'attributo
QueryProperty
allaclass
parola chiave , specificando il nome della proprietà della stringa di query e la proprietà della classe a cui viene eseguito il mapping,ItemId
rispettivamenteItemId
:[QueryProperty(nameof(ItemId), nameof(ItemId))] public partial class NotePage : ContentPage
Aggiungere una nuova
string
proprietà denominataItemId
. Questa proprietà chiama ilLoadNote
metodo , passando il valore della proprietà , che a sua volta deve essere il nome file della nota:public string ItemId { set { LoadNote(value); } }
Sostituire i
SaveButton_Clicked
gestori eDeleteButton_Clicked
con il codice seguente:private async void SaveButton_Clicked(object sender, EventArgs e) { if (BindingContext is Models.Note note) File.WriteAllText(note.Filename, TextEditor.Text); await Shell.Current.GoToAsync(".."); } private async void DeleteButton_Clicked(object sender, EventArgs e) { if (BindingContext is Models.Note note) { // Delete the file. if (File.Exists(note.Filename)) File.Delete(note.Filename); } await Shell.Current.GoToAsync(".."); }
I pulsanti sono ora
async
. Dopo aver premuto, la pagina torna alla pagina precedente usando un URI di..
.Eliminare la
_fileName
variabile dall'inizio del codice, perché non viene più usata dalla classe .
Modificare la struttura ad albero visuale dell'app
L'oggetto AppShell
sta ancora caricando la singola pagina della nota, ma deve caricare la visualizzazione AllPages. Aprire il file AppShell.xaml e modificare la prima ShellContent voce in modo che punti a AllNotesPage
invece di NotePage
:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Notes.Views"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate views:AllNotesPage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate views:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
Se si esegue l'app ora, si noterà che si arresta in modo anomalo se si preme il pulsante Aggiungi , lamentando che non può passare a NotesPage
. Ogni pagina che può essere spostata da un'altra pagina deve essere registrata con il sistema di spostamento. Le AllNotesPage
pagine e AboutPage
vengono registrate automaticamente nel sistema di spostamento dichiarando in TabBar.
Registrare con NotesPage
il sistema di spostamento:
Nel riquadro Esplora soluzioni aprire il file AppShell.xaml.cs.
Aggiungere una riga al costruttore che registra la route di navigazione:
namespace Notes; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute(nameof(Views.NotePage), typeof(Views.NotePage)); } }
Il metodo Routing.RegisterRoute
accetta due parametri:
- Il primo parametro è il nome stringa dell'URI da registrare, in questo caso il nome risolto è
"NotePage"
. - Il secondo parametro è il tipo di pagina da caricare quando
"NotePage"
si passa a .
È ora possibile eseguire l'app. Provare ad aggiungere nuove note, spostarsi tra le note e eliminare le note.
Esplorare il codice per questa esercitazione. Se si vuole scaricare una copia del progetto completato per confrontare il codice, scaricare questo progetto.
Congratulazioni!
L'esercitazione Creare un'app MAUI .NET è stata completata.
Passaggi successivi
Nella parte successiva della serie di esercitazioni si apprenderà come implementare modelli model-view-viewmodel (MVVM) nel progetto.
I collegamenti seguenti forniscono altre informazioni relative ad alcuni dei concetti appresi in questa esercitazione:
Hai un problema con questa sezione? In caso di problemi, fornisci feedback per contribuire al miglioramento della sezione.