0
votes

I have a UWP app which has 3 pages and third page contains a frame tag which loads multiple frames. Lets say I navigate to page 1->page 2-> Page 3->Frame 1-> Frame 2->Frame 3. If I press back button from frame 3 and 2 it goes to page 2 instead of frame 2 and frame 1 respectively. I have a common method to handle the back button event and it takes the root frame which is same for frame 1,2 and 3 which is page 3 and goes back to its back page page 2. So how can I go back to frames instead of the root page back. Below is the common back method I have in App.xaml.cs. Please help.

  protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;

        }
    }


    private void App_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
    {
        e.Handled = On_BackRequested();
    }



    private bool On_BackRequested()
    {
        Frame rootFrame = Window.Current.Content as Frame;



        if (rootFrame.CanGoBack)
        {
            rootFrame.GoBack();
            return true;
        }
        return false;
    }

public HomeView()
    {
        this.InitializeComponent();
        var vm = new HomeViewModel(new UserService(), new SubscriptionService(), new TransactionService(),new GameService());
        this.DataContext = vm;
        WalletBtn.Foreground = new SolidColorBrush(Colors.White);
        PaymentGrid = BuyModal;
        //PowerPassGameListGrid = PowerPassGameGrid;
       // SystemNavigationManager.GetForCurrentView().BackRequested += HomePage_BackRequested;
        PointBalance = wallet;
        //QueuedGames = QueueGame;
        //PowerPassSubscriptionGrid = PowerPass;
        SubmitPopUp = SuccessPopUp;
        RecentActivityGrid = RecentActivityModel;
        CurrentlyPickedPopUp = GamePickUp;
        PowerUpNavigationGrid = NavigationGrid;
    }
    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        string firstName = (string)ApplicationData.Current.LocalSettings.Values["FirstName"];
        string lastName = (string)ApplicationData.Current.LocalSettings.Values["LastName"];
        if (firstName != null && lastName != null)
        {
            welcomeMessage.Text = "Hi, " + firstName;
        }
    }
    public void MyWalletButton_Click(object sender, RoutedEventArgs e)
    {
        PowerPassBtn.Foreground = new SolidColorBrush(Colors.Gray);
        WalletBtn.Foreground = new SolidColorBrush(Colors.White);       
    }
    public void PowerPassButton_Click(object sender, RoutedEventArgs e)
    {
        PowerPassSelection();
    }

    //private void HomePage_BackRequested(object sender, BackRequestedEventArgs e)
    //{
    //    e.Handled = true;
    //    this.Frame.Navigate(typeof(LoginUsernameView));
    //}
    private void ButtonGotFocus(object sender, RoutedEventArgs e)
    {
        (sender as Button).Background = new SolidColorBrush(Colors.Green);
    }

    private void ButtonLostFocus(object sender, RoutedEventArgs e)
    {
        (sender as Button).Background = new SolidColorBrush(Colors.Transparent);
    }

    private void QueueButtonGotFocus(object sender, RoutedEventArgs e)
    {
        (sender as Button).Background = new SolidColorBrush(Colors.DeepSkyBlue);
    }

    private void QueueButtonLostFocus(object sender, RoutedEventArgs e)
    {
        (sender as Button).Background = new SolidColorBrush(Colors.Transparent);
    }

    private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);
        if (parent == null) return null;

        var parentT = parent as T;
        return parentT ?? FindParent<T>(parent);
    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        NavigationParameterDTO parameter = e.Parameter as NavigationParameterDTO;
        if (parameter != null)
        {
            if (parameter.FrameName == "WelcomeView")
            {
                HomeViewModel vm = this.DataContext as HomeViewModel;
                vm.PowerPassWelcomeFrame.Execute(null);
                PowerPassSelection();
            }
            else if(parameter.FrameName == "CheckOut")
            {
                HomeViewModel vm = this.DataContext as HomeViewModel;
                vm.PowerPassGameCheckOutMethod.Execute(null);
                PowerPassSelection();
            }
            else if(parameter.FrameName== "SignUp")
            {
                HomeViewModel vm = this.DataContext as HomeViewModel;
                vm.PowerPassFrame.Execute(null);
                PowerPassSelection();
            }
            else
            {
                HomeViewModel vm = this.DataContext as HomeViewModel;
                vm.PowerPassHomeFrame.Execute(null);
                PowerPassSelection();
            }
        }
    }

Xaml

                   <Button Style="{StaticResource PowerUpButtonStyle}"  x:Uid="Profile"  FontSize="36" Margin="0,60,0,0" Name="SettingsBtn" XYFocusDown="{x:Bind SettingsBtn}" FontFamily="Segoe Pro" Foreground="Gray" FocusVisualPrimaryThickness="0,0,0,3" FocusVisualMargin="10,0">
                        <Button.Background>
                            <SolidColorBrush Opacity="0"/>
                        </Button.Background>
                        <Button.Resources>
                            <ResourceDictionary>
                                <ResourceDictionary.ThemeDictionaries>
                                    <ResourceDictionary x:Key="Light">
                                        <SolidColorBrush x:Key="ButtonForegroundPointerOver" Color="White"/>
                                    </ResourceDictionary>
                                </ResourceDictionary.ThemeDictionaries>
                            </ResourceDictionary>
                        </Button.Resources>
                    </Button>
                </StackPanel>
                <Image Source="/Assets/Images/PURlogo_large.png" HorizontalAlignment="Left"  Margin="70,950" Width="212" Height="78"/>
            </Grid>
        </StackPanel>
        <Frame x:Name="MainFrame" Grid.Column="1" Content="{Binding FrameData,Mode=OneWay}" >
        </Frame>
        <Grid Background="Red" Visibility="Collapsed" x:Name="testgrid">
            <TextBlock Text="hello world"></TextBlock>
        </Grid>
    </Grid>
1
Can you explain how is the app structured? Do you actually have three different Frames? Or what is the distinction? Because you can't navigate from page to a frame and from a frame to another frame as described in the question - Martin Zikmund
I have 3 views and the third view contains the frames. First two pages are for login and the third page is the home page where there is a common menu and frame which changes according to the menu selection. - sadik
But then you have just single Frame on the last page, not three different ones, isn't that correct? My answer should be valid for this - Martin Zikmund
Sorry I am fairly new to the UWP. I mean frames will be loaded as if like a single page application. - sadik
Check my answer to see if that fits the issue or I can assist further :-) - Martin Zikmund

1 Answers

2
votes

Using Window.Current.Content gives you the very root Frame of the app. If you want to check if the Page3 is currently open and utilize its frames, you will have to do something like:

private bool On_BackRequested()
{
    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame.Content is Page3 page3 )
    {
         var innerFrame = page3.GetInnerFrame(); //implement this method in Page3
         if (innerFrame.CanGoBack)
         {
             innerFrame.GoBack();
             return true;
         }
    } 

    if (rootFrame.CanGoBack)
    {
        rootFrame.GoBack();
        return true;
    }
    return false;
}

The GetInnerFrame method will be in Page3 code-behind and will just return the frame that is on the page.

The code above will just navigate back with the frame that is within the Page3. If you nest further, you will again have to work with this frame's Content and so on.