dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

Is there a plan to add navigation functionality

Open 158545614 opened this issue 1 year ago • 1 comments

Overview

Is there a plan to add navigation functionality

API breakdown

Is there a plan to add navigation functionality

Usage example

Is there a plan to add navigation functionality

Breaking change?

Yes

Alternatives

Is there a plan to add navigation functionality

Additional context

Is there a plan to add navigation functionality

Help us help you

Yes, I'd like to be assigned to work on this item

158545614 avatar Dec 16 '24 05:12 158545614

Here are my two cents from implementing navigation using the Community Toolkit MVVM.

The main View has a content-presenting UI element that changes its content based on the currently set "Page." The content is changed by sending a NavigateToMessage via CT's WeakReferenceMessenger. Once sent, the requested view is found and loaded, parameters are passed down to it, and then it is set as the displayed content.

Remember to set the content on the UI thread.

This is relatively simple stuff.

It gets a bit more complicated when cancellable navigation is introduced. Imagine the application attempts to navigate somewhere while the user is on an editor page with unsaved changes. In such cases, the user should be prompted to save or discard their changes or cancel the navigation itself.

I've solved this by sending a PreviewNavigationMessage to every view once a NavigateToMessage is received by the NavigationManager. The PreviewNavigationMessage must be an AsyncRequestMessage<TaskCompletionSource<bool>>.

Why?

The view has a very limited time window to respond to this request message, which is too small to wait until the user clicks "Save", "Discard", "Cancel", or until data is saved into the database.

So, the request is responded to as soon as it is received, but with a TaskCompletionSource<bool>. That way, the NavigationManager can await until this type returns its value. This is sort of a hack to overcome that small time window.

NavigationManager sending and handling navigation cancellation:

    try
    {
      var message = new PreviewNavigationMessage(request);
      var cancelAwaiter = await WeakReferenceMessenger.Default.Send(message);
      var cancel = await cancelAwaiter.Task.ConfigureAwait(false);

      if (cancel)
      {
        NavigationLogger.LogNavigationCancelled(logger);
        return true;
      }
    }
    catch (InvalidOperationException)
    {
      // No response - nobody cancelled
    }

With this system, those who want to cancel will respond, and those who do not need any cancellation simply won't.


Hope this helps

hailstorm75 avatar May 03 '25 10:05 hailstorm75