本教程的這一部分加入了應用程式的最後一個元件,並在 所有筆記 頁面與個別 記事 頁面之間導航。
在撰寫任何程式代碼來處理應用程式內導覽之前,讓我們來描述預期的瀏覽行為。
在 AllNotesPage中,有現有筆記和 [ 新增筆記 ] 按鈕的集合。
- 點擊現有的附註應該跳轉至附註頁面,並載入已點擊的附註。
- 單擊 [ 新增筆記 ] 按鈕應該巡覽至記事頁面,並載入空的未儲存筆記。
在記事頁面上,您將新增 返回 按鈕,而且有 [ 儲存 ] 和 [ 刪除] 按鈕。
- 點擊 [上一頁] 按鈕應該返回到所有筆記頁面,放棄對筆記所做的任何更改。
- 點擊 刪除 按鈕應該刪除附註,然後返回上一頁。
新筆記
首先,你要負責新音符的導航。
小提示
你可以從
在 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)); }
每個 Page 都有一個 Frame 屬性,提供對 所屬 Page 實例的參考(如果有的話)。 這就是您在這裡呼叫的 Frame 的 Navigate 方法。 方法 Navigate 會採用您要巡覽的頁面 類型 。 您可以透過在 C# 中使用 Type 運算子來取得 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 ,以便不需選取它,您即可像按下按鈕一樣點擊某個專案。
小提示
你可以從
開啟 AllNotesPage.xaml。
更新
ItemsViewXAML,設置 SelectionMode = 為 None,並且將 IsItemInvokedEnabled =True。新增 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 3 標題列 控制項包含返回按鈕,符合 Fluent Design 的所有放置與外觀指引。 您將使用此內建按鈕進行返回流覽。
開啟 MainWindow.xaml。
更新 XAML,將
TitleBar= 和True系結至Frame.CanGoBack屬性。新增 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 方法,即可巡覽回先前的頁面。 最好先檢查 CanGoBack 屬性,再呼叫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,而在MainWindow中,您呼叫了rootFrame.GoBack。 這是因為 Page 類別具有 Frame 屬性,可取得裝載 Frame 的 Page(如果有的話)。 在此情況下,它會取得rootFrame的參考。
現在您可以執行您的應用程式。 請嘗試新增筆記、在筆記之間來回巡覽,以及刪除筆記。
在文檔中了解更多:
後續步驟
祝賀! 您已完成 建立 WinUI 應用程式 教學課程!
以下連結提供更多關於使用 WinUI 與 Windows 應用程式 SDK 建立應用程式的資訊: