Bob_Foo
Bob_Foo

Reputation: 23

UWP store frame on navigation

In my UWP app I want to use a frame for navigating between two(or more) pages. The content of a page is determined by the user by selecting from a list. When the selection of the list changes, the frame.Navigate() method gets called:

FruitsFrame.Navigate(typeof(ApplePage));

This works fine, but every time the mothod gets called a new instance is created thus discarding changes made to ApplePage.

My workaraound was to pass the ApplePage as parameter, but that felt quite wrong. I could use

FruitsFrame.Content = applePage;

instead, but OnNavigatedTo and OnNavigatedFrom won't get called. At the moment I rely on both events, beacause the start and stop task within the ApplePage.

So how can I use the page navigation properly? The only solution that comes to my mind is to build a wrapper class, that holds all information neccesary (including the tasks) which would be quite similar to a viewModel. Is this how frames were intended to use?

Upvotes: 0

Views: 445

Answers (2)

Hubii
Hubii

Reputation: 348

Just use the following Code:

>         public Page()
>         {
>             this.InitializeComponent();
>             this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
>         }

Upvotes: 1

Martin Zikmund
Martin Zikmund

Reputation: 39082

Frame is mostly intended to function as a holder for a navigation stack. As such it can hold the currently displayed page, the history of opened pages and their navigation parameters. In case the NavigationCache is enabled and NavigationCacheMode for individual pages is enabled, it can even keep the pages in the navigation stack in memory including the state of their controls.

In your case however it sounds like we are not talking about a "stack"-based navigation, but rather something like "tabs" - multiple pages of content that should stay in memory and should be restored. In this case you have two options.

The first is the one you already discovered - keeping the pages in memory and setting them as Content of a content control. It does not have to be a Frame per-se, but can instead be just a simple ContentControl or ContentPresenter. To make things even cleaner, you could then use UserControls instead of Pages, so that the navigation aspect of a page is clearly unavailable and you can't accidentally rely on the navigation events.

The second solution would be to actually use some kind of MVVM solution, which would allow you to keep in memory the associated ViewModel, which would contain the user-based state and would stay in memory, while the page and its UI would be destroyed. This is preferable, because UI-based controls do strain memory and simple data-based view model will be incomparably cheaper. In this case you would first navigate to the page and then check a view model locator for either a new or existing instance of the appropriate view model which you would set as the DataContext of your page. MvvmLight already offers a ViewModel locator out of the box, so it might be a good fit for your needs.

Upvotes: 0

Related Questions