在页面之间导航

本教程的这一部分将最后一部分添加到应用, 在所有备注 页和单个 备注 页之间导航。

在编写任何代码来处理应用内导航之前,让我们来描述预期的导航行为。

在其中 AllNotesPage,有现有笔记的集合和 “新建笔记 ”按钮。

  • 单击现有笔记应导航到备注页并加载已单击的笔记。
  • 单击“ 新建笔记 ”按钮应导航到备注页并加载空的未保存笔记。

在笔记页上,你将添加 一个后退 按钮,并且有 “保存 ”和 “删除 ”按钮。

  • 单击“后退”按钮应导航回所有备注页,放弃对笔记所做的任何更改。
  • 单击“ 删除 ”按钮应删除笔记,然后导航回去。

新笔记

首先,你将处理新笔记的导航。

小窍门

可以从 GitHub 存储库下载或查看本教程的代码。 若要查看此步骤中的代码,请参阅此提交: 导航 - 新注释

  1. AllNotesPage.xaml 中,查找 AppBarButton 新笔记。

  2. Click添加事件处理程序并将其重命名为 NewNoteButton_Click。 (如果需要提醒如何执行此作,请参阅备注页步骤中的 “添加事件处理程序 ”。

    <AppBarButton Icon="Add" Label="New note"
                  Click="NewNoteButton_Click"/>
    
  3. 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 。 现在,你将执行此作。

  1. 打开 NotePage.xaml.cs

  2. 添加代码以替代页面的 OnNavigatedTo 方法。

    public NotePage()
    {
        this.InitializeComponent();
    }
    //  ↓ Add this. ↓
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        noteModel = new Note();
    }
    

现在,导航到 NotePage该模型时,将创建模型的新实例 Note

现有笔记

现在,你将为现有笔记添加导航。 当前,单击笔记中的 ItemsView笔记时,会选中该笔记,但不会发生任何作。 大多数集合控件的默认行为是 单个选择,这意味着一次选择一个项。 你将更新 ItemsView 它,这样,你便可以单击一个类似按钮的项目,而不是选择它。

小窍门

可以从 GitHub 存储库下载或查看本教程的代码。 若要查看此步骤中的代码,请参阅此提交: 导航 - 最终应用

  1. 打开 AllNotesPage.xaml

  2. 使用 ItemsView = 和 IsItemInvokedEnabled = 更新 XAMLTrue

  3. ItemInvoked 事件添加处理程序。

    <ItemsView ItemsSource="{x:Bind notesModel.Notes}"
               Grid.Row="1" Margin="24" 
               ItemTemplate="{StaticResource NoteItemTemplate}"
               <!-- ↓ Add this. ↓ -->
               SelectionMode="None"
               IsItemInvokedEnabled="True"
               ItemInvoked="ItemsView_ItemInvoked">
    
  4. AllNotesPage.xaml.cs中,找到该方法 ItemsView_ItemInvoked 。 (如果 Visual Studio 未为你创建它,则复制并粘贴代码时可能会发生这种情况,请在下一步中添加它。

  5. 在方法中 ItemsView_ItemInvoked ,添加要导航到 NotePage的代码。 这一次,你将使用 Navigate 方法的重载,使你能够将对象传递给其他页面。 将调用 Note 作为第二个导航参数传递。

    private void ItemsView_ItemInvoked(ItemsView sender, ItemsViewItemInvokedEventArgs args)
    {
        Frame.Navigate(typeof(NotePage), args.InvokedItem);
    }
    
  6. 打开 NotePage.xaml.cs

  7. 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 页面的模型。 如果不是 nullNote请像以前一样创建新 Note 项。

返回导航

最后,需要更新应用,以便你可以从单个笔记导航回所有备注页。

WinUI TitleBar 控件包含一个后退按钮,它符合放置和外观的所有 Fluent Design 指南。 你将使用此内置按钮进行后退导航。

  1. 打开 MainWindow.xaml

  2. 使用 TitleBar = 和绑定到 True 属性的 IsBackButtonEnabled 更新 XAML

  3. 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 事件处理程序。 这是将代码放回的位置。

  4. 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 ,以在删除笔记后导航回去。

  1. 打开 NotePage.xaml.cs

  2. 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 创建应用的详细信息: