Cache di navigazione e notifica di modifica

Il primo passaggio consiste nell'eseguire la configurazione di base per le modifiche da apportare:

  • abilitare la cache di navigazione.
  • implementare le notifiche di modifica delle proprietà per la Note.Text proprietà .

Una volta fatto, adatterai altre parti dell'app affinché funzionino con queste modifiche.

Suggerimento

È possibile scaricare o visualizzare il codice completo per questa esercitazione dal repository GitHub WinUI Notes part 2. Per visualizzare le differenze tra i punti di inizio e di fine per il progetto, vedere questo commit: aggiornamenti per la parte 2.

Abilita NavigationCacheMode

Per impostazione predefinita, viene creata una nuova istanza di Page con i relativi valori predefiniti ogni volta che si verifica lo spostamento. Nell'app Note WinUI, è anche qui che viene creato il notesModel, che archivia tutte le istanze di Note.

In AllNotesPage.xaml, impostare NavigationCacheMode su Enabled (NavigationCacheMode="Enabled"). Con NavigationCacheMode abilitato, la stessa istanza di pagina viene mantenuta, quindi non viene creata una nuova istanza di Page a ogni navigazione e notesModel non viene ricreato.

<Page
    x:Class="WinUI_Notes.Views.AllNotesPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUI_Notes.Views"
    xmlns:models="using:WinUI_Notes.Models"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    //  ↓ Add this. ↓
    NavigationCacheMode="Enabled">

Eseguire l'app ora e si noteranno alcuni effetti collaterali di questa modifica.

  1. Quando si modifica una nota esistente, le modifiche non vengono riflesse nella pagina all-notes quando si torna indietro.
  2. Quando si crea e si salva una nuova nota, non viene visualizzata nell'elenco all-notes quando si torna indietro.
  3. Quando si elimina una nota esistente, non viene rimossa dall'elenco all-notes quando si torna indietro.

Questi problemi verranno risolti successivamente.

Per altre informazioni, vedere la documentazione:

Implementare INotifyPropertyChanged

Quando si modifica e si salva una nota esistente, la modifica viene salvata nel file system, ma la modifica non viene propagata all'elenco di tutte le note. Ciò è dovuto al fatto che la classe Note non notifica al data binding, che connette TextBox al testo Note, che è avvenuto un aggiornamento. Perché questa notifica avvenga, la classe Note deve implementare l'interfaccia INotifyPropertyChanged per la proprietà Text.

Note

WinUI include l'interfaccia Microsoft.UI.Xaml.Data.INotifyPropertyChanged. Viene usato solo dalle app C++, che non usano .NET.

Le app C# create con .NET usano invece l'interfaccia System.ComponentModel.INotifyPropertyChanged.

L'implementazione di INotifyPropertyChanged segue un modello set.

  1. Aggiungere using istruzioni per i namespace necessari.

    // ↓ Add this. ↓
    using System.ComponentModel
    using System.Runtime.CompilerServices
    
  2. Implementare INotifyPropertyChanged. La Note classe implementa ora questa interfaccia.

    // ↓ Update this. ↓
    public class Note : INotifyPropertyChanged
    
  3. Creare un campo sottostante (_text) per la Text proprietà .

    // ↓ Delete this. ↓
    // public string Text { get; set; } = string.Empty;
    
    // ↓ Add this. ↓
    private string _text = string.Empty;
    
  4. Modificare la Text proprietà per usare un modello getter/setter con notifica di modifica delle proprietà.

    // ↓ Add this. ↓
    public string Text
    {
        get => _text;
        set
        {
            if (_text != value)
            {
                _text = value;
                OnPropertyChanged();
            }
        }
    }
    
  5. Aggiungere l'evento PropertyChanged richiesto dall'interfaccia INotifyPropertyChanged .

    // ↓ Add this. ↓
    public event PropertyChangedEventHandler? PropertyChanged;
    
  6. Aggiungere il metodo OnPropertyChanged. Questo metodo di supporto attiva l'evento PropertyChanged usando l'attributo CallerMemberName per il rilevamento automatico del nome della proprietà.

    // ↓ Add this. ↓
    protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    

Suggerimento

Puoi usare GitHub Copilot per implementare INotifyPropertyChanged rapidamente nell'app. Queste modifiche al codice sono state generate con il prompt: "Implement INotifyPropertyChanged per la proprietà Note.Text".

Modalità di binding

A questo punto, la Text proprietà invia una notifica a tutti gli elementi dell'interfaccia utente associati ogni volta che cambia il valore, in modo che l'interfaccia utente possa essere aggiornata automaticamente. Tuttavia, affinché gli elementi dell'interfaccia utente associata reagiscano alla notifica di aggiornamento, è necessario assicurarsi che venga usato BindingMode corretto.

Importante

È importante scegliere il BindingMode corretto; in caso contrario, il data binding potrebbe non funzionare come previsto. Un errore comune con {x:Bind} è dimenticare di modificare l'impostazione predefinita BindingMode quando OneWay o TwoWay è necessario.

Nome Description
OneTime Aggiorna la proprietà di destinazione solo alla creazione del binding. Impostazione predefinita per {x:Bind}.
OneWay Aggiorna la proprietà di destinazione al momento della creazione del binding. Anche le modifiche apportate all'oggetto di origine possono essere propagate alla destinazione.
TwoWay Aggiorna la destinazione o l'oggetto di origine quando vengono apportate modifiche. Quando viene creata l'associazione, la proprietà di destinazione viene aggiornata dall'origine.

In AllNotesPage.xaml, trova NoteItemTemplate in Page.Resources. Quindi, nel modello trovare l'oggetto TextBlock associato alla Text proprietà . Aggiorna il binding per usare la modalità di binding OneWay.

// ↓ Update this. ↓              ↓    ↓
<TextBlock Text="{x:Bind Text, Mode=OneWay}"
           Margin="4" TextWrapping="Wrap"
           TextTrimming="WordEllipsis"/>

Poiché l'utente non può aggiornare il testo in TextBlock, è necessaria solo un'associazione OneWay , dall'origine (Note.Text) alla destinazione (TextBlock.Text).

Per altre informazioni, vedere la documentazione: