1

I have a problem with the navigation of Frame in UWP.

I have a frame (Frame 1) defined in MainPage.xaml and only one page (Page 1) will be loaded by this frame. Page 1 also has a frame (called SubPageFrame, collapsed) and some other contents (BasicContent, visible). SubPageFrame could navigate pages by this order:

Page 1-1 -> Page 1-2 -> Page 1-3 -> ... -> GoBack() -> ... -> Page 1-1

Here is the part of XAML:

<!-- This Grid is contained in Page 1. -->
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ScrollViewer Name="BasicContentScrollViewer" VerticalScrollBarVisibility="Auto">
        <!-- BasicContent -->
    </ScrollViewer>

    <Frame Name="SubPageFrame" Visibility="Collapsed">
        <!--Page 1-x will be loaded here-->
    </Frame>
</Grid> 

When I navigate to Page 1-1, I will collapse the ScrollViewer and display SubPageFrame. When I return to the Page 1-1 I loaded firstly, obviously I can't use SubPageFrame.GoBack() to get BasicContent. So I use the property CanGoBack to check the BackStack when I want to display BasicContent:

if(SubPageFrame.CanGoBack  == false)
{
    //collapse SubPageFrame
    //display ScrollViewer
}

But this operation means Page 1-1 still be kept in SubPageFrame. When I use SubPageFrame again, its BackStack will contains Page 1-1 and the new Page. It can be predicted that every time I want to return to BasicContent I must go back to Page 1-1 whether or not I have called Page 1-1.

I have two steps to test my code and here is a picture to describe the two steps: here.

After step 1, I still get Page 1-1 in step 2, which is not what I expect.

My problem is when I go back to Page 1-1, I can make BasicContent visible (it's OK) and make SubPageFrame return to its initial state (the frame doesn't contain any page).

I can't find any method to do it.

How can I clear a BackStack of a Frame? The first page navigated by SubPageFrame does not seem to be removed by SubPageFrame.BackStack.Clear().

Or is there a better solution for my code?

Chester Gu
  • 23
  • 6
  • 1
    Possible duplicate of [Clear Back Stack Navigation Windows 10](http://stackoverflow.com/questions/31886251/clear-back-stack-navigation-windows-10) – Bart Oct 04 '16 at 09:49
  • So you want to make the BasicContent collapsed first when you navigate forward to page 1-1, and make it visible again when you navigate back to page 1-1? – Grace Feng Oct 05 '16 at 02:19
  • @GraceFeng-MSFT: When I navigate back to page 1-1 and want to return to BasicC,ntent, I can't see BasicContent. So to make it visible I directly collapse the Frame 1-1 (it contains Page 1-1). Because BasicContent will refresh with the method GoBack(), so I use this new frame (Frame 1-1) to load remaining pages (Page 1-x). – Chester Gu Oct 05 '16 at 03:09
  • @ChesterGu, please confirm my question, yes or no? I can't understand what you are doing, or maybe you can post your xaml code? Or some pictures to explain what you want to do? – Grace Feng Oct 05 '16 at 03:18
  • @GraceFeng-MSFT: No, when I return to Page 1-1, the BasicContent is still be collapsed. I have updated me question with XAML code. The SubPageFrame (Frame 1-1) will load all sub pages. – Chester Gu Oct 05 '16 at 04:32
  • @Bart: It didn't work. After I loaded Page 1-1, the BackStackDepth was 0, not 1. Then I cleared the stack and loaded Page 1-1 and Page 1-2. The BackStackDepth was 1, not 2. BackStack.Clear() didn't remove the first page. So I think the first page is not kept in the BackStack but other place? – Chester Gu Oct 05 '16 at 04:47
  • @ChesterGu, OK, then when do you want to make the BasicContent collapsed and when do you want to make it visible? When the content of your Frame1-1 is null, your BasicContent is visible? Your problem is when navigate back to page 1-1, you still want to go back to null content state? – Grace Feng Oct 05 '16 at 05:49
  • @GraceFeng-MSFT: Sorry for my unclear expression. BasicContent will be collapsed once the Frame 1-1 navigates to any page. That's why I put the BasicContent and Frame 1-1 in the same Grid. For your last question, the answer is yes. I want to go back to null content state in order to wait for a new navigation. – Chester Gu Oct 05 '16 at 06:43

1 Answers1

1

I'm not sure about what you want to do and base on your last comment, I discussed with my colleague, maybe what you need is just setting the content of Frame to null when CanGoBack is false?

For example like this:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ScrollViewer Name="BasicContentScrollViewer" VerticalScrollBarVisibility="Auto">
        <Rectangle Height="3000" Width="3000" Fill="LightBlue" />
    </ScrollViewer>

    <Frame Name="SubPageFrame" Visibility="Collapsed">
        <!--Page 1-x will be loaded here-->
    </Frame>

    <Button Content="Go Back" VerticalAlignment="Bottom" HorizontalAlignment="Left" Click="Back_Button_Click" />
    <Button Content="Go to Page 1-1" VerticalAlignment="Bottom" HorizontalAlignment="Right" Click="Forward_Button_Click" />
</Grid>

code behind:

private void Back_Button_Click(object sender, RoutedEventArgs e)
{
    if (SubPageFrame.CanGoBack)
        SubPageFrame.GoBack();
    else
    {
        SubPageFrame.Content = null;
        SubPageFrame.Visibility = Visibility.Collapsed;
        BasicContentScrollViewer.Visibility = Visibility.Visible;
    }
}

private void Forward_Button_Click(object sender, RoutedEventArgs e)
{
    SubPageFrame.Navigate(typeof(MainPage));
    BasicContentScrollViewer.Visibility = Visibility.Collapsed;
    SubPageFrame.Visibility = Visibility.Visible;
}

If there still has problem, please leave a comment to let us know. An image to show what you want is better.

Update:

private void Back_Button_Click(object sender, RoutedEventArgs e)
{
    if (SubPageFrame.CanGoBack)
    {
        var backstack = SubPageFrame.BackStack;
        if (backstack.Count > 1)
        {
            SubPageFrame.GoBack();
        }
        else
        {
            SubPageFrame.BackStack.Clear();
            SubPageFrame.Visibility = Visibility.Collapsed;
            BasicContentScrollViewer.Visibility = Visibility.Visible;
        }
    }
    else
    {
        SubPageFrame.Visibility = Visibility.Collapsed;
        BasicContentScrollViewer.Visibility = Visibility.Visible;
    }
}
Grace Feng
  • 16,564
  • 2
  • 22
  • 45
  • I want to give a picture but my reputation is not enough. Your code is similar to mine, but `SubPageFrame.Content = null;` is no use. – Chester Gu Oct 05 '16 at 08:40
  • @ChesterGu, you can upload to other place like OneDrive, and paste the uri here. – Grace Feng Oct 05 '16 at 08:42
  • I have uploaded a [picture](https://1drv.ms/i/s!As0B8evn1Xrig59oaLVZd0-jDgocpA) to OneDrive. Hope this make my problem more clear. There are two steps to test the problem. After step 1, Page 1-1 will be stored in SubPageFrame and I can't remove it. – Chester Gu Oct 05 '16 at 09:26
  • @ChesterGu, I finally found your problem, good question, I updated my answer for back button. Please have a check. If this solve your issue, could you please mark this answer? – Grace Feng Oct 05 '16 at 10:14
  • It still have problem with my logic. Step 1 is just a simple example. If there are two or more pages in step 1 to navigate, the BackButton will go back to BasicContent directly and jump over other pages. – Chester Gu Oct 05 '16 at 10:38
  • For example, I tested two pages (Page 1-1, then Page 1-2) in step 1. When I called GoBack() in the Page 1-2, the `backstack.count` is 1 and the Page 1-1 will be lost. – Chester Gu Oct 05 '16 at 10:45
  • @ChesterGu, This is all because the `Frame` has no backstack when it is used for navigation for the first time, I think it is by design. Just be curious, is that possible to make your BasicContent as a Page and navigate in your Frame1-1 to this page when it is initialized? It should solve the problem then? – Grace Feng Oct 06 '16 at 01:16
  • I have tried this method to solve my problem, but it's not in my demand. BasicContent has something dynamic I want to keep. You know BackStack just stores the navigation request but not the whole page. So the BasicContent will be refreshed every time I call GoBack() to return to it. – Chester Gu Oct 06 '16 at 02:33
  • @ChesterGu, no, you can store the cache for this page. See my [answer here](http://stackoverflow.com/questions/35944277/uwp-page-state-manage/35980891#35980891). – Grace Feng Oct 06 '16 at 02:41