Condividi tramite


Creare una pagina per una nota

A questo punto si creerà una pagina che consente a un utente di modificare una nota e quindi si scriverà il codice per salvare o eliminare la nota.

Suggerimento

È possibile scaricare o visualizzare il codice per questa esercitazione dal repository GitHub. Per visualizzare il codice così com'è in questo passaggio, vedere la pagina commit: nota - iniziale.

Aggiungere prima di tutto la nuova pagina al progetto:

  1. Nel riquadro Esplora soluzioni di Visual Studio fare clic con il pulsante destro del mouse sul progetto >Aggiungi>nuovo elemento....

  2. Nella finestra di dialogo Aggiungi nuovo elemento selezionare WinUI nell'elenco dei modelli sul lato sinistro della finestra. Selezionare quindi il modello Pagina vuota (WinUI 3). Assegnare al file il nome NotePage.xamle quindi selezionare Aggiungi.

  3. Il NotePage.xaml file verrà aperto in una nuova scheda, visualizzando tutto il markup XAML che rappresenta l'interfaccia utente della pagina. Sostituire l'elemento <Grid> ... </Grid> nel codice XAML con il markup seguente:

    <Grid Padding="16" RowSpacing="8">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    
        <TextBox x:Name="NoteEditor"
             AcceptsReturn="True"
             TextWrapping="Wrap"
             PlaceholderText="Enter your note"
             Header="New note"
             ScrollViewer.VerticalScrollBarVisibility="Auto"
             Width="400"
             Grid.Column="1"/>
    
        <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Right"
                Spacing="4"
                Grid.Row="1" Grid.Column="1">
            <Button Content="Save" Style="{StaticResource AccentButtonStyle}"/>
            <Button Content="Delete"/>
        </StackPanel>
    </Grid>
    
  4. Salvare il file premendo CTRL+S, facendo clic sull'icona Salva nella barra degli strumenti oppure selezionando il menu Salva>NotePage.xaml .

    Se si esegue l'app in questo momento, non verrà visualizzata la pagina della nota appena creata. Ciò è dovuto al fatto che è comunque necessario impostarlo come contenuto del Frame controllo in MainWindow.

  5. Aprire MainWindow.xaml e impostare NotePage come SourcePageType in Frame, come illustrato di seguito:

    <Frame x:Name="rootFrame" Grid.Row="1"
           SourcePageType="local:NotePage"/>
    

    Quando si esegue l'app, l'oggetto Frame caricherà un'istanza di NotePage e la visualizzerà all'utente.

Importante

I mapping dello spazio dei nomi XAML (xmlns) sono la controparte XAML dell'istruzione C# using . local: è un prefisso mappato automaticamente all'interno delle pagine XAML per il progetto dell'app (xmlns:local="using:WinUINotes"). Viene mappato per fare riferimento allo stesso spazio dei nomi creato per contenere l'attributo e il x:Class codice per tutti i file XAML, incluso App.xaml. Se definisci tutte le classi personalizzate che vuoi usare in XAML in questo stesso spazio dei nomi, puoi usare il local: prefisso per fare riferimento ai tipi personalizzati in XAML.

Suddividere le parti principali dei controlli XAML presenti nella pagina:

Interfaccia utente della nuova pagina note con la griglia evidenziata da Visual Studio.

  • Grid.RowDefinitions e Grid.ColumnDefinitions definiscono una griglia con 2 righe e 3 colonne (posizionate sotto la barra del titolo).

    • La riga inferiore viene ridimensionata automaticamente (Auto) per adattarne il contenuto, i due pulsanti. La riga superiore usa tutto lo spazio verticale rimanente (*).
    • La colonna centrale è 400a larghezza epx ed è la posizione in cui viene inserito l'editor delle note. Le colonne su entrambi i lati sono vuote e suddividono tutti gli spazi orizzontali rimanenti tra di essi (*).

    Annotazioni

    A causa del funzionamento del sistema di ridimensionamento, quando progetti la tua app XAML, stai lavorando in pixel efficaci, non in pixel fisici reali. I pixel effettivi (epx) sono un'unità virtuale di misura e vengono usati per esprimere dimensioni e spaziatura del layout, indipendentemente dalla densità dello schermo.

  • <TextBox x:Name="NoteEditor" ... > ... </TextBox> è un controllo di immissione di testo (TextBox) configurato per la voce di testo a più righe e viene posizionato nella cella centrale superiore di Grid (Grid.Column="1"). Gli indici di riga e colonna sono basati su 0 e, per impostazione predefinita, i controlli vengono inseriti nella riga 0 e nella colonna 0 dell'elemento padre Grid. Si tratta quindi dell'equivalente di specificare riga 0, colonna 1.

  • <StackPanel Orientation="Horizontal" ... > ... </StackPanel> definisce un controllo layout (StackPanel) che impila i relativi elementi figlio verticalmente (impostazione predefinita) o orizzontalmente. Si trova nella cella centrale inferiore del (GridGrid.Row="1" Grid.Column="1").

    Annotazioni

    Grid.Row="1" Grid.Column="1" è un esempio di proprietà associate XAML. Le proprietà associate consentono a un oggetto XAML di impostare una proprietà che appartiene a un oggetto XAML diverso. Spesso, come in questo caso, gli elementi figlio possono usare proprietà associate per informare il relativo elemento padre di come devono essere presentati nell'interfaccia utente.

  • Due <Button> controlli si trovano all'interno di <StackPanel> e disposti orizzontalmente. Si aggiungerà il codice per gestire gli eventi Click dei pulsanti nella sezione successiva.

Per altre informazioni, vedere la documentazione:

Caricare e salvare una nota

Aprire il NotePage.xaml.cs file code-behind. Quando si aggiunge un nuovo file XAML, il code-behind contiene una singola riga nel costruttore, una chiamata al InitializeComponent metodo :

namespace WinUINotes
{
    public sealed partial class NotePage : Page
    {
        public NotePage()
        {
            this.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.

A questo punto si aggiungerà il NotePage.xaml.cs codice al file code-behind per gestire il caricamento e il salvataggio delle note.

  1. Aggiungere le dichiarazioni di variabili seguenti alla NotePage classe :

    public sealed partial class NotePage : Page
    {
        private StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        private StorageFile? noteFile = null;
        private string fileName = "note.txt";
    

    Quando una nota viene salvata, viene salvata nella risorsa di archiviazione locale dell'app come file di testo.

    Usare la classe StorageFolder per accedere alla cartella dati locale dell'app. Questa cartella è specifica per l'app, quindi le note salvate qui non possono essere accessibili da altre app. Usare la classe StorageFile per accedere al file di testo salvato in questa cartella. Il nome del file è rappresentato dalla fileName variabile . Per il momento, impostare su fileName "note.txt".

  2. Creare un gestore eventi per l'evento Loaded della pagina della nota.

    public NotePage()
    {
        this.InitializeComponent();
        // ↓ Add this. ↓
        Loaded += NotePage_Loaded;
    }
    
    // ↓ Add this event handler method. ↓
    private async void NotePage_Loaded(object sender, RoutedEventArgs e)
    {
        noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName);
        if (noteFile is not null)
        {
            NoteEditor.Text = await FileIO.ReadTextAsync(noteFile);
        }
    }
    

    In questo metodo si chiama TryGetItemAsync per recuperare il file di testo dalla cartella . Se il file non esiste, restituisce null. Se il file esiste, chiamare ReadTextAsync per leggere il testo dal file nella NoteEditor proprietà Text del controllo. Tenere presente che NoteEditor è il TextBox controllo creato nel file XAML. È possibile farvi riferimento qui nel file code-behind usando l'oggetto x:Name assegnato.

    Importante

    È necessario contrassegnare questo metodo con la async parola chiave perché le chiamate di accesso ai file sono asincrone. In breve, se si chiama un metodo che termina in ...Async (ad esempio TryGetItemAsync), è possibile aggiungere l'operatore await alla chiamata. In questo modo il codice successivo non viene eseguito fino al completamento della chiamata attesa e mantiene reattivo l'interfaccia utente. Quando si usa await, il metodo da cui si sta chiamando deve essere contrassegnato con la parola chiave asincrona . Per altre info, vedi Chiamare API asincrone in C#.

Per altre informazioni, vedere la documentazione:

Aggiungere gestori eventi

Aggiungere quindi i gestori eventi Click per i pulsanti Salva ed Elimina . L'aggiunta di gestori eventi è un'operazione che verrà eseguita spesso durante la creazione delle app, quindi Visual Studio offre diverse funzionalità per semplificare l'operazione.

  1. NotePage.xaml Nel file posizionare il cursore dopo l'attributo Content nel controllo SalvaButton. Digitare Click=. A questo punto, Visual Studio dovrebbe visualizzare un'interfaccia utente di completamento automatico simile alla seguente:

    Screenshot dell'interfaccia utente di completamento automatico del nuovo gestore eventi di Visual Studio nell'editor XAML

    • Premere il tasto freccia giù per selezionare <Nuovo gestore eventi>, quindi premere TAB. Visual Studio completerà l'attributo con Click="Button_Click" e aggiungerà un metodo del gestore eventi denominato Button_Click nel NotePage.xaml.cs file code-behind.

    A questo momento, è necessario rinominare il Button_Click metodo in qualcosa di più significativo. Questa operazione verrà eseguita nei passaggi seguenti.

  2. In NotePage.xaml.cstrovare il metodo aggiunto per l'utente:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    
    }
    

    Suggerimento

    Per individuare il codice nell'app, fare clic su Cerca nella barra del titolo di Visual Studio e usare l'opzione Ricerca codice . Fare doppio clic sul risultato della ricerca per aprire il codice nell'editor di codice.

    Funzionalità di ricerca in Visual Studio

  3. Posizionare il cursore prima di "B" in Button e digitare Save. Attendere un attimo e il nome del metodo verrà evidenziato in verde.

  4. Quando si passa il puntatore del mouse sul nome del metodo, Visual Studio visualizzerà una descrizione comando con un cacciavite o un'icona a forma di lampadina. Fare clic sul pulsante freccia giù accanto all'icona, quindi fare clic su Rinomina 'Button_Click' su 'SaveButton_Click'.

    Il metodo di Visual Studio rinomina l'interfaccia utente popup.

    Visual Studio rinomina il metodo ovunque nell'app, incluso nel file XAML in cui è stato aggiunto per la prima volta a Button.

  5. Ripetere questi passaggi per il pulsante Elimina e rinominare il metodo in DeleteButton_Click.

Ora che i gestori eventi sono collegati, è possibile aggiungere il codice per salvare ed eliminare il file della nota.

  1. Aggiungere questo codice nel SaveButton_Click metodo per salvare il file. Si noti che è anche necessario aggiornare la firma del metodo con la async parola chiave .

    private async void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        if (noteFile is null)
        {
            noteFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        }
        await FileIO.WriteTextAsync(noteFile, NoteEditor.Text);
    }
    

    SaveButton_Click Nel metodo verificare prima di tutto se noteFile è stato creato. Se è null, è necessario creare un nuovo file nella cartella di archiviazione locale con il nome rappresentato dalla fileName variabile e assegnare il file alla noteFile variabile. Quindi, si scrive il testo nel TextBox controllo nel file rappresentato da noteFile.

  2. Aggiungere questo codice nel DeleteButton_Click metodo per eliminare il file. È necessario aggiornare anche la firma del metodo con la async parola chiave qui.

    private async void DeleteButton_Click(object sender, RoutedEventArgs e)
    {
        if (noteFile is not null)
        {
            await noteFile.DeleteAsync();
            noteFile = null;
            NoteEditor.Text = string.Empty;
        }
    }
    

    DeleteButton_Click Nel metodo verificare prima di tutto se noteFile esiste. In caso affermativo, eliminare il file rappresentato dalla noteFile cartella di archiviazione locale e impostare su noteFilenull . Reimpostare quindi il testo nel TextBox controllo su una stringa vuota.

    Importante

    Dopo l'eliminazione del file di testo dal file system, è importante impostare su noteFilenull. Tenere presente che noteFile è un file di archiviazione che fornisce l'accesso al file di sistema nell'app. Dopo l'eliminazione del file di sistema, noteFile punta comunque alla posizione in cui si trovava il file di sistema, ma non sa che non esiste più. Se si tenta di leggere, scrivere o eliminare il file di sistema, verrà visualizzato un errore.

  3. Salvare il file premendo CTRL+S, facendo clic sull'icona Salva nella barra degli strumenti oppure selezionando il menu Salva>NotePage.xaml.cs .

Il codice finale per il file code-behind dovrebbe essere simile al seguente:

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using Windows.Storage;

namespace WinUINotes
{
    public sealed partial class NotePage : Page
    {
        private StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        private StorageFile? noteFile = null;
        private string fileName = "note.txt";

        public NotePage()
        {
            this.InitializeComponent();
            Loaded += NotePage_Loaded;
        }

        private async void NotePage_Loaded(object sender, RoutedEventArgs e)
        {
            noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName);
            if (noteFile is not null)
            {
                NoteEditor.Text = await FileIO.ReadTextAsync(noteFile);
            }
        }

        private async void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            if (noteFile is null)
            {
                noteFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
            }
            await FileIO.WriteTextAsync(noteFile, NoteEditor.Text);
        }

        private async void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            if (noteFile is not null)
            {
                await noteFile.DeleteAsync();
                noteFile = null;
                NoteEditor.Text = string.Empty;
            }
        }
    }
}

Testare la nota

Con questo codice sul posto, è possibile testare l'app per assicurarsi che la nota venga salvata e caricata correttamente.

  1. Compilare ed eseguire il progetto premendo F5, facendo clic sul pulsante Debug "Start" nella barra degli strumenti oppure selezionando il menu Esegui>debug avvia debug.
  2. Digitare nella casella di testo e premere il pulsante Salva .
  3. Chiudere l'app, quindi riavviarla. La nota immessa deve essere caricata dalla risorsa di archiviazione del dispositivo.
  4. Premere il pulsante Elimina .
  5. Chiudere l'app, riavviarla. Verrà visualizzata una nuova nota vuota.

Importante

Dopo aver confermato che il salvataggio e l'eliminazione di una nota funzionano correttamente, creare e salvare di nuovo una nuova nota. Si vuole avere una nota salvata per testare l'app nei passaggi successivi.