uno.extensions
uno.extensions copied to clipboard
navigator.GetDataAsync fails when navigating within lower levels. Only works for (Wasm/Android/iOS)
Current behavior
When using Uno.Toolkit.UI Navigation, I've come across an issue where on the return from await navigator.GetDataAsync , it only works as expected under WASM/Android/iOS, not for UWP/WinUI?
On all frameworks, when executing the following command from a toplevel MainPage, navigating to another page (level2), passing data and expect returned data using the following instructions, it works fine:
var result = await navigator.GetDataAsync<ResponseData>(this, data: new CommandData { Message = "Data from MainPage" });
Name = result.Message;
The component bound to the Name value updates nicely on the page.
However, for UWP/WinUI, when I navigate to the second page (level2), then navigate to another page (level3), again using the same command :
var result = await navigator.GetDataAsync<ResponseData>(this, data: new CommandData { Message = "Data from SecondPage" });
Name = result.Message;
It returns fine from the third page BUT...
Another instance of the second page's viewmodel gets instantiated (i.e. the constructor runs) directly after the GetDataAsync returns.
AND whatever UI activities resume thereafter, does not update e.g. the Name = result.Message is not updating the UI. I think it's because the datacontext viewmodel has changed.
So, the question is. Why does GetDataAsync work when navigating away from the first level, but fails when navigating from within lower levels (SecondPage to ThirdPage)
I've provided a simple example project solution that demonstrates the issue
It's here: https://github.com/hbraasch/UnoNavigatorTester.git
Expected behavior
When GetDataAsync returns, the viewmodel must not be re-instantiated, and any UI activities after the return in the same method must be effective
As I mentioned, it works fine under WASM/Android/iOS?
How to reproduce it (as minimally and precisely as possible)
Install the solution: https://github.com/hbraasch/UnoNavigatorTester.git
Run until you reach this page:
Not the textbox displays [Value set by MainPage]. We want to modify this on return from the next level navigation; Press the [Go directly to third page] button. See this display:
This is the page that supplies data for return to the calling page. Press the [Go back] button. You are now back to MainPage and see the value updated to [DataFromThirdPage]
This demonstrates correct operation when navigating from root level
Now press the [Go to second page] button. See this display:
Not the textbox displays [Value set by SecondPage]. We want to modify this on return from the next level navigation; Press the [Go to third page] button. See this display:
This is the page that supplies data for return to the calling page. Press the [Go back] button. See what displays next:
Notice the textbox still displays [Value set by SecondPage]. No update.
The exact same WASM result:
If you set breakpoints inside the SecondPageViewModel, you will notice its constructor fired unexpectedly.
Workaround
I've discover that during the re-instantiation of the viewmodel, the correct ResponseData object is returned through injection. By adding this to the constructor, one can retrieve and update UI elements.
public SecondViewModel(INavigator navigator, string command, ResponseData response)
However, to make use of this makes for for ugly coding, especially if the viewmodel gets data from other routes too, and these data will be null when this constructor gets called at that instance. It completely defeats the purpose of await/async.
I was hoping the viewmodel will not be instantiated when GetDataAsync returns, so one can carry on thereafter and simply update the "need to change" UI elements.
Works on UWP/WinUI
Works perfectly under WASM/Android/iOS
iOS
Not for UWP/WinUI
Environment
Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia, Other
NuGet package version(s)
N/A
Affected platforms
Windows (WinAppSDK), Desktop
IDE
Visual Studio 2022
IDE version
N/A
Relevant plugins
N/A
Anything else we need to know?
N/A