There is an unsaved comment in progress. You will lose your changes if you continue. Are you sure you want to reopen the work item?
VisualStateAwarePage page state is broken for cached pages
Suppose we have a
VisualStateAwarePage instance with
NavigationCacheMode set to
Required. The first time this page is navigated to, a session state entry is created with key "Page-n" where n is equal to the current back stack depth (see the
OnNavigatedTo() method of the
VisualStateAwarePage class). If this page is navigated to again, then a new session state entry is not created, and the old page state dictionary is reused with the previous key "Page-n". The
problem is, in my app, this particular cached page can exist in many different positions in the back stack.
Here's an example "backstack" (leftmost DetailsPage is the current page at time of app termination).
DetailsPage [Page-1] <- PreviewPage [Page-2] <- DetailsPage [Page-1] <- FirstPage [Page-0]
Here, the DetailsPage instance is cached, and different data is displayed for this page in the first and third back stack slots (i.e. the navigation parameter is different for those entries). All is good when the DetailsPage is displayed for the first time,
but when it is displayed again it reuses the previous page state entry "Page-1" instead of "Page-3". When the app terminates, the session state dictionary is saved to storage. Then when the app is launched, the saved session state is loaded
from storage and the frame navigation state is restored (see
SessionStateService.RestoreFrameNavigationState()). This causes the
OnNavigatedTo() method of the DetailsPage to be called, where it sets the
_pageKey to "Page-3", which is correct for a non-cached page, but in fact the correct key should be "Page-1". This causes a KeyNotFoundException (since the page key doesn't exist in the state dictionary), and then the exception
is caught silently in MvvmAppBase without giving the navigation service a chance to restore the saved navigation. This leaves the DetailsPage in an inconsistent state (the
OnNavigatedTo() method of my DetailsPageViewModel isn't called).