本教程的这一部分将最后一部分添加到应用, 在所有备注 页和单个 备注 页之间导航。
在编写任何代码来处理应用内导航之前,让我们来描述预期的导航行为。
在其中 AllNotesPage,有现有笔记的集合和 “新建笔记 ”按钮。
- 单击现有笔记应导航到备注页并加载已单击的笔记。
 - 单击“ 新建笔记 ”按钮应导航到备注页并加载空的未保存笔记。
 
在笔记页上,你将添加 一个后退 按钮,并且有 “保存 ”和 “删除 ”按钮。
- 单击“后退”按钮应导航回所有备注页,放弃对笔记所做的任何更改。
 - 单击“ 删除 ”按钮应删除笔记,然后导航回去。
 
新笔记
首先,你将处理新笔记的导航。
小窍门
可以从 GitHub 存储库下载或查看本教程的代码。 若要查看此步骤中的代码,请参阅此提交: 导航 - 新注释。
在 AllNotesPage.xaml 中,查找
AppBarButton新笔记。Click添加事件处理程序并将其重命名为NewNoteButton_Click。 (如果需要提醒如何执行此作,请参阅备注页步骤中的 “添加事件处理程序 ”。<AppBarButton Icon="Add" Label="New note" Click="NewNoteButton_Click"/>在
NewNoteButton_Click方法( AllNotesPage.xaml.cs中),添加以下代码:private void NewNoteButton_Click(object sender, RoutedEventArgs e) { // ↓ Add this. ↓ Frame.Navigate(typeof(NotePage)); }
每个 页面 都有一个 Frame 属性,该属性提供对属于的 Frame 实例 Page 的引用(如果有)。 这就是 Frame 你在此处调用 Navigate 方法。 该方法 Navigate 采用要导航到的页面 的类型 。 使用Type运算符在 C# 中获取该typeof作。
如果现在运行应用,可以单击“ 新建笔记 ”按钮导航到笔记页,并且可以键入笔记编辑器。 但是,如果尝试保存笔记,则不会发生任何作。 这是因为尚未在笔记页中创建模型的实例 Note 。 现在,你将执行此作。
打开 NotePage.xaml.cs。
添加代码以替代页面的 OnNavigatedTo 方法。
public NotePage() { this.InitializeComponent(); } // ↓ Add this. ↓ protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); noteModel = new Note(); }
现在,导航到 NotePage该模型时,将创建模型的新实例 Note 。
现有笔记
现在,你将为现有笔记添加导航。 当前,单击笔记中的 ItemsView笔记时,会选中该笔记,但不会发生任何作。 大多数集合控件的默认行为是 单个选择,这意味着一次选择一个项。 你将更新 ItemsView 它,这样,你便可以单击一个类似按钮的项目,而不是选择它。
小窍门
可以从 GitHub 存储库下载或查看本教程的代码。 若要查看此步骤中的代码,请参阅此提交: 导航 - 最终应用。
打开 AllNotesPage.xaml。
使用
ItemsView= 和 IsItemInvokedEnabled = 更新 XAMLTrue。为 ItemInvoked 事件添加处理程序。
<ItemsView ItemsSource="{x:Bind notesModel.Notes}" Grid.Row="1" Margin="24" ItemTemplate="{StaticResource NoteItemTemplate}" <!-- ↓ Add this. ↓ --> SelectionMode="None" IsItemInvokedEnabled="True" ItemInvoked="ItemsView_ItemInvoked">在 AllNotesPage.xaml.cs中,找到该方法
ItemsView_ItemInvoked。 (如果 Visual Studio 未为你创建它,则复制并粘贴代码时可能会发生这种情况,请在下一步中添加它。在方法中
ItemsView_ItemInvoked,添加要导航到NotePage的代码。 这一次,你将使用 Navigate 方法的重载,使你能够将对象传递给其他页面。 将调用Note作为第二个导航参数传递。private void ItemsView_ItemInvoked(ItemsView sender, ItemsViewItemInvokedEventArgs args) { Frame.Navigate(typeof(NotePage), args.InvokedItem); }打开 NotePage.xaml.cs。
OnNavigatedTo更新方法重写以处理Note调用所Navigate传递的重写。protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // ↓ Update this. ↓ if (e.Parameter is Note note) { noteModel = note; } else { noteModel = new Note(); } // ↑ Update this. ↑ }在此代码中,首先检查传递 的参数 是否为
Note对象。 如果是,则将其分配为Note页面的模型。 如果不是null,Note请像以前一样创建新Note项。
返回导航
最后,需要更新应用,以便你可以从单个笔记导航回所有备注页。
WinUI TitleBar 控件包含一个后退按钮,它符合放置和外观的所有 Fluent Design 指南。 你将使用此内置按钮进行后退导航。
打开 MainWindow.xaml。
使用
TitleBar= 和绑定到True属性的 IsBackButtonEnabled 更新 XAML。为 BackRequested 事件添加处理程序。 XAML 应如下所示:
<TitleBar x:Name="AppTitleBar" Title="WinUI Notes" IsBackButtonVisible="True" IsBackButtonEnabled="{x:Bind rootFrame.CanGoBack, Mode=OneWay}" BackRequested="AppTitleBar_BackRequested">此处, IsBackButtonVisible 属性设置为
true. 这使得后退按钮显示在应用窗口的左上角。然后, IsBackButtonEnabled 属性绑定到 Frame.CanGoBack 属性,因此仅当帧可以导航回时,才启用后退按钮。
最后,添加了 BackRequested 事件处理程序。 这是将代码放回的位置。
在 MainWindow.xaml.cs中,将此代码添加到
AppTitleBar_BackRequested方法:private void AppTitleBar_BackRequested(TitleBar sender, object args) { // ↓ Add this. ↓ if (rootFrame.CanGoBack == true) { rootFrame.GoBack(); } // ↑ Add this. ↑ }该
Frame类跟踪其 BackStack 中的导航,因此只需调用 GoBack 方法即可导航回以前的页面。 最好在调用前始终检查GoBack属性。
接下来,需要更新代码 NotePage ,以在删除笔记后导航回去。
打开 NotePage.xaml.cs。
在
DeleteButton_Click删除注释后,使用对Frame.CanGoBack方法的调用更新事件处理程序方法:private async void DeleteButton_Click(object sender, RoutedEventArgs e) { if (noteModel is not null) { await noteModel.DeleteAsync(); } // ↓ Add this. ↓ if (Frame.CanGoBack == true) { Frame.GoBack(); } // ↑ Add this. ↑ }
小窍门
你可能已经注意到,在NotePage你打电话时Frame.GoBack,你打电话MainWindowrootFrame.GoBack。 这是因为 Page 类具有一个 Frame 属性,该属性获取 Frame 承载的 PageFrame 属性(如果有)。 在本例中,它获取对 rootFrame. 的引用。
现在可以运行应用了。 尝试添加新笔记、在笔记之间来回导航以及删除笔记。
              
               在文档中了解详细信息:
后续步骤
祝贺! 你已完成 “创建 WinUI 应用 ”教程!
以下链接提供有关使用 WinUI 和 Windows 应用 SDK 创建应用的详细信息: