Передайте заметку в качестве параметра навигации

Теперь, когда у Note есть State, обновите навигацию, чтобы передать его обратно в AllNotesPage, где вы сможете обработать его соответствующим образом в зависимости от его State. Это также дает возможность улучшить взаимодействие с пользователем, связанное с навигацией.

Tip

При необходимости ознакомьтесь с руководством по заметкам: переход между страницами. Прежде чем вносить эти изменения, рекомендуется понять, как настроена навигация.

В настоящее время все переходы назад от NotePage к AllNotesPage выполняются с помощью простого вызова Frame.GoBack. Однако метод GoBack не позволяет передавать параметр навигации. Чтобы передать Note в качестве параметра, вам потребуется заменить навигацию назад на переход вперёд (Frame.Navigate). GoBack также не добавляет запись в стек навигации, как это происходит при переходе вперёд, поэтому вам потребуется управлять стеком возврата, чтобы этот переход вперёд не был добавлен в стек.

Tip

Вы можете скачать или просмотреть полный код для этого руководства из репозитория GitHub в WinUI Notes часть 2. Чтобы увидеть различия между начальным и конечным состоянием проекта, см. этот коммит: обновления для части 2.

OnNavigatingFrom

В NotePage.cs переопределите метод OnNavigatingFrom. Это вызывается после того, как пользователь нажимает кнопку "Назад" и вызывается GoBack . Он позволяет перехватывать навигацию, проверять заметку Stateи отменять навигацию при необходимости.

Здесь, если заметка не сохранена, вы отмените обратную навигацию и отобразите диалоговое окно, которое спрашивает, хочет ли пользователь сохранить заметку.

  • Если пользователь сохраняет заметку, вызовите SaveAsync, затем замените навигацию назад вызовом Navigate, передающим заметку в AllNotesPage.
  • Если пользователь не сохраняет свои изменения, используйте TextBox.Undo , чтобы отменить изменения, сбросить состояние заметки и перезапустить обратную навигацию.
// ↓ Add this. ↓
protected async override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (noteModel?.State == NoteState.Unsaved)
    {
        e.Cancel = true;
        ContentDialog dialog = new ContentDialog();

        // XamlRoot must be set for the ContentDialog.
        dialog.XamlRoot = this.XamlRoot;
        dialog.Title = "Save your work?";
        dialog.PrimaryButtonText = "Save";
        dialog.SecondaryButtonText = "Don't Save";
        dialog.CloseButtonText = "Cancel";
        dialog.DefaultButton = ContentDialogButton.Primary;

        ContentDialogResult result = await dialog.ShowAsync();

        if (result == ContentDialogResult.Primary)
        {
            await noteModel.SaveAsync();
            Frame.Navigate(typeof(AllNotesPage), noteModel);
        }
        else if (result == ContentDialogResult.Secondary)
        {
            while (NoteEditor.CanUndo)
            {
                NoteEditor.Undo();
            }
            NoteEditor.Focus(FocusState.Programmatic);
            noteModel.State = NoteState.Saved;
            Frame.Navigate(typeof(AllNotesPage), noteModel);
        }
    }
}

Delete

Затем измените код события кнопки Click удаления.NotePage.xaml.cs Вместо простого удаления заметки и перехода назад вы проверите состояние заметки.

  • Если состояние — Unset — это означает, что заметка только что создана, в неё не вносили изменений и она не была сохранена, — просто вернитесь назад. Не нужно передавать заметку в качестве параметра.
  • В противном случае удалите файл заметок из файловой системы и передайте Note объект обратно в качестве параметра навигации. Затем AllNotesPage получит Note в состоянии Deleted и поймёт, что его нужно удалить из коллекции Notes.
private async void DeleteButton_Click(object sender, RoutedEventArgs e)
{
    if (noteModel is not null)
    {
        if (noteModel.State == NoteState.Unset)
        {
            // If the note is new, doesn't have any edits,
            // and hasn't been saved, just call GoBack.
            // There's no need to pass back the noteModel.
            if (Frame.CanGoBack == true)
            {
                Frame.GoBack();
            }
        }
        else
        {
            // If the note has been saved before, then delete it
            // and navigate back to the AllNotesPage passing the
            // noteModel with its Deleted state.
            await noteModel.DeleteAsync();
            Frame.Navigate(typeof(AllNotesPage), noteModel);
        }
    }
}

Сохранить и закрыть

В настоящее время пользователю нужно щелкнуть, чтобы сохранить заметку, а затем щелкнуть стрелку назад, чтобы закрыть страницу заметки и вернуться к коллекции заметок. Это можно улучшить, предоставив пользователю сохранить и закрыть заметку одним щелчком мыши. Для этого замените кнопку "Сохранить" на кнопку "Сохранить и закрыть" SplitButton с пунктом "Сохранить" в раскрывающемся списке.

<!-- ↓ Delete this. ↓ -->
<!--<Button Content="Save" Click="SaveButton_Click"/>-->

<!-- ↓ Add this. ↓ -->
<SplitButton Content="Save &amp; close" Click="SaveCloseButton_Click"
             Height="32">
    <SplitButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem Text="Save" Click="SaveButton_Click"/>
        </MenuFlyout>
    </SplitButton.Flyout>
</SplitButton>

Добавьте новый обработчик событий для события кнопки Click "Сохранить и закрыть". Здесь вы сохраняете заметку, а затем передаете ее обратно AllNotesPage в качестве параметра навигации.

// ↓ Add this. ↓
private async void SaveCloseButton_Click(SplitButton sender, SplitButtonClickEventArgs args)
{
    if (noteModel is not null)
    {
        await noteModel.SaveAsync();
        Frame.Navigate(typeof(AllNotesPage), noteModel);
    }
}

Обработка параметра навигации в AllNotesPage

В AllNotesPage необходимо обработать входной параметр навигации (Note) и при необходимости добавить его в коллекцию Notes или удалить из неё.

Чтобы обработать входящий параметр навигации, переопределите метод OnNavigatedTo , как показано здесь.

// ↓ Add this. ↓
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is Note note)
    {
        if (note.State == NoteState.Deleted)
        {
            notesModel.RemoveNote(note);
        }
        else if (!notesModel.Notes.Contains(note))
        {
            notesModel.AddNote(note);
        }
        // This navigation should be treated like a
        // back navigation, so clear the backstack.
        Frame.BackStack.Clear();
    }
}

Теперь вы можете запустить приложение, чтобы узнать, как работают эти изменения. Попробуйте добавить новые заметки, перейти между заметками и удалить их.

Дополнительные сведения см. в документации:

Дальнейшие действия

Поздравляем! Вы завершили руководство «Заметки WinUI», часть 2!

Следующие ссылки содержат дополнительные сведения о создании приложений с помощью WinUI и Windows App SDK: