unoplatform / uno.extensions

Libraries to ease common developer tasks associated with building multi-platform mobile, desktop and web applications using Uno Platform or WinAppSDK.
https://platform.uno/
Other
73 stars 47 forks source link

[Navigation] Incorrect ViewModel created on sequential navigation between different item types #1604

Open Nurgo opened 1 year ago

Nurgo commented 1 year ago

Current behavior

I have 2 classes 'Item1' and 'Item2', with associated Pages and ViewModels.

I use nested navigation to display these objects in a Frame.

  1. I start by navigating to an object of type 'Item1', all goes well, an 'Item1ViewModel' is created and displayed in the Frame.
  2. I then navigate to an object of type 'Item2', all goes well, an 'Item2ViewModel' is created and displayed in the Frame.
  3. I navigate again to an object of type 'Item1', but an 'Item2ViewModel' is created, linked to no 'Item2', the content of the Frame is not updated.

Here's the definition of the ViewMap and RouteMap I'm using:

private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes) {
  views.Register(
      new ViewMap(ViewModel: typeof(ShellViewModel)),
      new ViewMap<MainPage, MainViewModel>(),
      new DataViewMap<Item1View, Item1ViewModel, Item1>(),
      new DataViewMap<Item2View, Item2ViewModel, Item2>()
  );

  routes.Register(
      new RouteMap("", View: views.FindByViewModel<ShellViewModel>(),
          Nested: new RouteMap[]
          {
              new RouteMap("Main", View: views.FindByViewModel<MainViewModel>(), Nested: new RouteMap[] {
                  new RouteMap("Details")
              }),
              new RouteMap("Item1", View: views.FindByData<Item1>()),
              new RouteMap("Item2", View: views.FindByData<Item2>())
          }
      )
  );
}

And here is how I navigate between items:

...
_navigator.NavigateRouteAsync(this, "./Details/Item1", data: _selectedItem1);
...
_navigator.NavigateRouteAsync(this, "./Details/Item2", data: _selectedItem2);
...

Expected behavior

In step 3, an 'Item1ViewModel' should have been created, not an 'Item2ViewModel'.

How to reproduce it (as minimally and precisely as possible)

Here is a minimal project to reproduce the problem: FrameNavigationUno.zip

Environment

Nuget Package:

Package Version(s):

Tested on 2.3.10 and 2.4.2.

Affected platform(s):

Visual Studio:

Relevant plugins:

nickrandolph commented 1 year ago

I think what's happening is that it's detecting that Item1 is in the back stack, so is just causing current page to refresh. Do you intend to have multiple instances of item1 in the backstack? Also, what's the relationship between Main, Details and Item1/2 are they all just page navigational on the frame? If so, don't use nested routes - this is only used when you have nested regions eg Tabs inside a Page

Nurgo commented 1 year ago

Hi @nickrandolph, thank you for your response.

I don't think this is the cause of the problem. I've tried adding the item ID to the navigation path and the problem still occurs.

"Main" is the main page, "Detail" is a Frame within the main page, which is used to display the Item1View and Item2View pages.

I'm not sure I fully understand the role of nested routes, but I've tried without them with the same result: when I navigate back to an Item1 object after displaying an Item2, the Navigator no longer creates the correct ViewModel. You can easily reproduce this problem with the small project I've included.

What I want is simply to be able to navigate between pages of different types within a Frame. Am I doing it wrong?

Nurgo commented 1 year ago

Hi @nickrandolph,

I've been working extensively on this issue and have tried almost every navigation method available, including the use of query parameters in the routes. Despite all efforts, the problem persists: Uno Extensions seems unable to sequentially display multiple types of ViewModels within the same frame.

I've attached a minimalistic project to the initial post to demonstrate the issue. I strongly believe this is a bug within Uno Extensions and would greatly appreciate it if you could take the time to test the attached project and look into this matter.

Thank you for your attention to this issue.

nickrandolph commented 1 year ago

Navigation on the frame currently doesn't support having the same page appear multiple times in the backstack - we detect that the page is in the back stack so attempt to update the current viewmodel. This is a bug. However, the workaround for what you want to do is to change the Frame to be a ContentControl - this will work unless you need the Frame to support going back to previous pages

Nurgo commented 1 year ago

Thanks for your quick response, your workaround did the trick!

nickrandolph commented 1 year ago

I'll leave this issue open for the moment as I think we should add support for having the same page on the backstack multiple times. The exception to this will be if the page is the current page and you're attempting to navigate to the same page. In this case the page will just be updated with a new view model instance

agneszitte commented 5 months ago

@nickrandolph what is the status lately for this issue please?