by Andreas Hammar - .Net
In Windows 8 Metro apps, the navigation model has been improved over the previous one found on Windows Phone. One difference is that page caching has to be manually enabled for each page, as we explained in part 8 of our Windows Phone to Windows 8 conversion series. And, the page cache is active for both forward and backward navigation, which recently gave me some headaches. The solution is to clear the cache when backing away from the page, and forcing other pages to always be cached.
Activating the page cache is as easy as setting the NavigationCacheMode property
|
1 |
NavigationCacheMode = NavigationCacheMode.Enabled; |
in the constructor of the page.
What gave me problems was navigating back from a page and then forward to it again. The system was keeping the page cached anyway and I had some weird behavior such as the back button being in it’s hover state instead of neutral. Also the SemanticZoom control on the page would sometimes not show any items at all.
So, I wanted to have the cache enabled for the page when returning to if from a page further down the stack – but have the page removed from the cache when backing away from it. I could not find a way to manipulate the contents of the cache, so instead I went with clearing the cache instead.
There is no direct method to clear the cache, but you can set the size of the cache. So, when backing away from the page in question, I execute this code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { base.OnNavigatingFrom(e); if (e.NavigationMode == NavigationMode.Back) { ResetPageCache(); } } private void ResetPageCache() { var cacheSize = ((Frame) Parent).CacheSize; ((Frame) Parent).CacheSize = 0; ((Frame) Parent).CacheSize = cacheSize; } |
Of course, clearing the cache will clear all the pages from the cache, not just the page in question. To force the other pages that I wanted to keep cached to survive the cache clearing – I instead set those to
|
1 |
NavigationCacheMode = NavigationCacheMode.Required; |
which is the stricter form of caching. This will cause the page not be put the page cache that the user controls the size of, but to be cached elsewhere, hence be immune to my clearing of the cache.
Setting some pages to NavigationCacheMode.Required and clearing the cache when backing away from a single page is of course not a clean cut solution, but it works for me here. The app I’m working on fairly small and the other pages work well with this scenario. For a larger app I would probably go for fixing the page that did not behave well instead of impacting all other pages.
Worth mentioning is that I tried to set NavigationCacheMode.Disabled when navigating away from the page, but that did not stop it from being cached. I guess that once it’s been put in the cache it is not taken away by just setting the property again.
Happy coding, ciao!
I’m having problems implementing this… “Parent” is null
Are you in a Page that is set as the content of a Frame?
Where do execute the code, a system callback (e.g. NavigatedTo)?
You’re welcome to post your code :)
It works fine, thanks!
Hello.
Thank you for sharing this piece of code! Do you know if there is a way to clear the navigation-cache in metro javascript applications?
Hi,
Sorry I’m not that into the JS stack. Good luck!