Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The first step is to do the basic setup for the changes you need to make:
- enable the navigation cache.
- implement property change notifications for the
Note.Textproperty.
One that's done, you'll adapt other parts of the app to work with these changes.
Tip
You can download or view the completed code for this tutorial from the GitHub repo at WinUI Notes part 2. To see the differences between the start and end points for the project, see this commit: updates for part 2.
Enable NavigationCacheMode
By default, a new Page instance is created with its default values every time navigation occurs. In the WinUI Notes app, this is also where the notesModel, which stores all the Note instances, is created.
In AllNotesPage.xaml, set NavigationCacheMode to Enabled (NavigationCacheMode="Enabled"). With NavigationCacheMode enabled, the same page instance is kept around, so a new Page instance isn't created on each navigation, and notesModel is not re-created.
<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">
Run the app now and you'll notice some side effects of this change.
- When you edit an existing note, your changes aren't reflected in the all-notes page when you navigate back.
- When you create and save a new note, it doesn't appear in the all-notes list when you navigate back.
- When you delete an existing note, it's not removed from the all-notes list when you navigate back.
You'll fix these issues next.
Learn more in the docs:
Implement INotifyPropertyChanged
When you edit and save an existing note, your change is saved to the file system, but the change isn't propagated to the all-notes list. This is because the Note class doesn't notify the data binding, which connects the TextBox to the Note text, that an update has occurred. To make this notification happen, the Note class needs to implement the INotifyPropertyChanged interface for its Text property.
Note
WinUI includes the Microsoft.UI.Xaml.Data.INotifyPropertyChanged interface. This is used only by C++ apps, which don't use .NET.
C# apps created with .NET use the System.ComponentModel.INotifyPropertyChanged interface instead.
The implementation of INotifyPropertyChanged follows a set pattern.
Add
usingstatements for the required namespaces.// ↓ Add this. ↓ using System.ComponentModel using System.Runtime.CompilerServicesImplement
INotifyPropertyChanged. TheNoteclass now implements this interface.// ↓ Update this. ↓ public class Note : INotifyPropertyChangedCreate a backing field (
_text) for theTextproperty.// ↓ Delete this. ↓ // public string Text { get; set; } = string.Empty; // ↓ Add this. ↓ private string _text = string.Empty;Modify the
Textproperty to use a getter/setter pattern with property change notification.// ↓ Add this. ↓ public string Text { get => _text; set { if (_text != value) { _text = value; OnPropertyChanged(); } } }Add the PropertyChanged event required by the
INotifyPropertyChangedinterface.// ↓ Add this. ↓ public event PropertyChangedEventHandler? PropertyChanged;Add the
OnPropertyChangedmethod. This helper method raises thePropertyChangedevent using the CallerMemberName attribute for automatic property name detection.// ↓ Add this. ↓ protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
Tip
You can use GitHub Copilot to quickly implement INotifyPropertyChanged in your app. These code changes were generated with the prompt: "Implement INotifyPropertyChanged for the Note.Text property".
Binding mode
Now the Text property will notify any UI elements bound to it whenever its value changes, so your UI can be updated automatically. However, in order for the bound UI elements to react to the update notification, you have to ensure the correct BindingMode is used.
Important
It's important to choose the correct BindingMode; otherwise, your data binding might not work as expected. (A common mistake with {x:Bind} is to forget to change the default BindingMode when OneWay or TwoWay is needed.)
| Name | Description |
|---|---|
OneTime |
Updates the target property only when the binding is created. Default for {x:Bind}. |
OneWay |
Updates the target property when the binding is created. Changes to the source object can also propagate to the target. |
TwoWay |
Updates either the target or the source object when either changes. When the binding is created, the target property is updated from the source. |
In AllNotesPage.xaml, find the NoteItemTemplate in Page.Resources. Then, in the template, find the TextBlock that's bound to the Text property. Update the binding to use the OneWay binding mode.
// ↓ Update this. ↓ ↓ ↓
<TextBlock Text="{x:Bind Text, Mode=OneWay}"
Margin="4" TextWrapping="Wrap"
TextTrimming="WordEllipsis"/>
Since the user can't update the text in the TextBlock, only a OneWay binding is needed, from the source (Note.Text) to the target (TextBlock.Text).
Learn more in the docs:
Windows developer