How can I remove pages from a Frame's history?
Asked Answered
J

3

3

How can I manipulate a Frame's history in a WinRT XAML app?

The user will start on my hub page, where they can select an existing project to go to its edit screen, or they can select "new project". "New project" will take them through a short wizard, then take them to the "edit project" screen.

It makes sense for the wizard pages to just be pages that I navigate to in the frame; that way the user can back out of the wizard if they change their mind. (It'll only be two pages, so "back" can take the place of "cancel".) But once the wizard is done and the changes are committed, there's no longer any reason for those wizard pages to be in the history; if the user clicks Back from the "edit project" page, I want them to go right back to the hub.

To illustrate, I want the flow to look something like this:

  • Frame history: Hub. User clicks "New Project".
  • Frame history: Hub -> Wizard Page 1. User clicks "Next".
  • Frame history: Hub -> Wizard Page 1 -> Wizard Page 2. User clicks "Finish".
  • Frame history: Hub -> Edit Project.

Frame doesn't seem to have any methods along the lines of "remove from history". The docs do have hints that there might be some way to override the history, because the docs for GoBack say "Navigates to the most recent item in back navigation history, if a Frame manages its own navigation history" (emphasis mine), but that's all it has to say on the topic -- there's no mention of how someone else can manage history for it. So I don't know whether that's useful or not.

How can I remove my wizard pages from my Frame's history once the user completes the wizard?

Jackal answered 30/6, 2012 at 23:55 Comment(3)
I've had the same problem Joe, and I'm thinking we may have to wrap the Frame in a custom NavigationService class, and maintain the history stack ourselves. (And set the Frame's BackStackDepth to zero - so that it doesn't)Medicaid
@Krishna, does NavigationService even exist in WinRT? I can't find it in the docs, and if I type the class name into my code, VS doesn't prompt me to add the appropriate using.Jackal
I'm sorry - I should have been a bit more clear. I mentioned a custom NavigationService, like the one shown in this answer: #10971523 - something like that could be extended to include navigation history.Medicaid
B
6

You can remove pages from the history by calling SetNavigationState(string navigationState) on the frame. Unfortunately the format of the serialized navigationState is "for internal use only", so just changing the string might break your code in future versions.

I only can think of a future proof method to completely clear the navigation stack:

  1. At program startup save the empty navigation state by calling GetNavigationState.
  2. BEFORE calling Navigate for your Edit Project page, call SetNavigationState with the empty navigation state.

Your Edit Project page will now be the first page on the stack.

Boulogne answered 9/10, 2012 at 11:11 Comment(3)
Yeah, this is an idea I considered. I actually wound up rethinking my UI and getting rid of the page navigation completely, instead swapping out UI in an MVVM fashion, and replacing the wizard with one side-scrolling page; I think the end result us much more Metro^H^H^H^H^H Windows Store than a wizard would have been anyway. But I think this would be a good answer for the question as I originally asked it.Jackal
@JoeWhite, hi, I'm wondering how do you swap out UI in a MVVM fashion. I stumble upon similar problem and want to learn from you.Maiolica
@imgen, take a look at this video: "Build Your Own MVVM Framework". Good stuff about driving your UI from your viewmodels, including navigation. You can also check out Caliburn.Micro, the MVVM framework he wrote after he gave this talk; the very latest version (released yesterday!) is supposed to support WinRT.Jackal
T
1

Starting with Windows 8.1, you have access to the BackStack property of a Frame. You can easily remove some content or clear the whole back stack.

Here is what I'm using the clear the back stack :

var rootFrame   = (Window.Current.Content as Frame);
rootFrame.Navigate(typeof(MyPage));
rootFrame.BackStack.Clear();
Thermel answered 23/3, 2015 at 14:34 Comment(0)
M
0

its a solution for me :

while (ContentFrame.BackStack.Count > 1)
            {
              ContentFrame.BackStack.Remove(ContentFrame.BackStack.ElementAt(ContentFrame.BackStack.Count-1));

            }
Milano answered 24/4, 2016 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.