简体   繁体   English

SplitView和后退按钮导航-UWP-C#

[英]SplitView and Back Button Navigation - UWP - C#

I am currently learning C# in UWP environment. 我目前正在UWP环境中学习C#。 I have a test app which is having a bit of the problem as described in Splitview with frame and navigating to another page, back button does not work . 我有一个测试应用程序,该应用程序有一些问题,如Splitview中所述, 带有框架并导航到另一页,后退按钮不起作用
But the my code is a little different from the above page. 但是我的代码与上面的页面略有不同。

My App.xaml.cs has the following code: 我的App.xaml.cs具有以下代码:

namespace Testing
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
        //NavigationCacheMode.Enabled;
    }

    /// <summary>
    /// Invoked when the application is launched normally by the end user.  Other entry points
    /// will be used such as when the application is launched to open a specific file.
    /// </summary>
    /// <param name="e">Details about the launch request and process.</param>
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
#if DEBUG
        if (System.Diagnostics.Debugger.IsAttached)
        {
            this.DebugSettings.EnableFrameRateCounter = true;
        }
#endif
        Frame rootFrame = Window.Current.Content as Frame;

        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active
        if (rootFrame == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();

            rootFrame.NavigationFailed += OnNavigationFailed;

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }



            // Place the frame in the current Window
//--------------------------------------------------------------------
            //Window.Current.Content = new SplitShellPage(rootFrame);
//--------------------------------------------------------------------
            Window.Current.Content = rootFrame;
        }
        if (e.PrelaunchActivated == false)
        {
            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }

            Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;

            // Ensure the current window is active
            Window.Current.Activate();
        }
    }

    /// <summary>
    /// Invoked when Navigation to a certain page fails
    /// </summary>
    /// <param name="sender">The Frame which failed navigation</param>
    /// <param name="e">Details about the navigation failure</param>
    void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
    {
        throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
    }

    /// <summary>
    /// Invoked when application execution is being suspended.  Application state is saved
    /// without knowing whether the application will be terminated or resumed with the contents
    /// of memory still intact.
    /// </summary>
    /// <param name="sender">The source of the suspend request.</param>
    /// <param name="e">Details about the suspend request.</param>
    private void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        //TODO: Save application state and stop any background activity
        deferral.Complete();
    }
    private void App_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if (rootFrame == null)
            return;

        // Navigate back if possible, and if the event has not 
        // already been handled .
        if (rootFrame.CanGoBack && e.Handled == false)
        {
            e.Handled = true;
            rootFrame.GoBack();
        }
    }


}

}

If I use Window.Current.Content = new SplitShellPage(rootFrame); 如果我使用Window.Current.Content = new SplitShellPage(rootFrame); as in place of Window.Current.Content = rootFrame; 如代替Window.Current.Content = rootFrame; the SplitView works but the back button does not work. SplitView有效,但后退按钮无效。 If I use the second line then SplitView doesn't work but back navigation works. 如果我使用第二行,则SplitView不起作用,但向后导航起作用。

I even tried setting my launch page to SplitView page as rootFrame.Navigate(typeof(SplitShellPage), e.Arguments); 我什至尝试将启动页面设置为rootFrame.Navigate(typeof(SplitShellPage), e.Arguments);SplitView页面rootFrame.Navigate(typeof(SplitShellPage), e.Arguments); but that causes the application to stop at runtime and the application doesn't start. 但这会导致应用程序在运行时停止,并且应用程序无法启动。

The other pages with code are as: 其他带有代码的页面如下:

SplitShellPage.xaml.cs SplitShellPage.xaml.cs

namespace Testing.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SplitShellPage : Page
 {

    public SplitShellPage(Frame frame)
    {
        this.InitializeComponent();
        NavigationCacheMode = NavigationCacheMode.Enabled;
        shell_splitview.Content = frame;
        (shell_splitview.Content as Frame).Navigate(typeof(MainPage));
    }

    private void hamburger_btn_Click(object sender, RoutedEventArgs e)
    {
        shell_splitview.IsPaneOpen = !shell_splitview.IsPaneOpen;
    }
 }
}

This method of work I found when searching on google to make the NavigationPane work in all the pages and it does work in all the pages just without the Back Navigation . 我在Google上进行搜索时发现的这种工作方法,使NavigationPane可以在所有页面中使用,并且它在所有页面中都可以使用,而无需使用Back Navigation

MainPage.xaml.cs MainPage.xaml.cs

namespace Testing
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
 {
    public MainPage()
    {
        this.InitializeComponent();
        NavigationCacheMode = NavigationCacheMode.Enabled;
    }


    private void Settings_Flyout_Click(object sender, RoutedEventArgs e)
    {
        this.Frame.Navigate(typeof(SettingsPage));
    }
 }
}


I have done some searches on google but nothing makes sense because they use some other methods and things get more complicated. 我已经在Google上进行了一些搜索,但是没有任何意义,因为它们使用了其他方法,并且事情变得更加复杂。 Please let me know what I am doing wrong here and how to make it right. 请让我知道我在这里做错了什么以及如何做对了。 Thanks. 谢谢。
PS Let me know if I need to also share the XAML files. PS让我知道是否还需要共享XAML文件。

If I use Window.Current.Content = new SplitShellPage(rootFrame); 如果我使用Window.Current.Content = new SplitShellPage(rootFrame); as in place of Window.Current.Content = rootFrame; 如代替Window.Current.Content = rootFrame; the SplitView works but the back button does not work SplitView有效,但后退按钮无效

In this situation, the frame currently you are using is shell_splitview.Content . 在这种情况下,当前使用的框架是shell_splitview.Content Because you are using this code for navigating (shell_splitview.Content as Frame).Navigate(typeof(MainPage)); 因为您正在使用此代码进行导航(shell_splitview.Content as Frame).Navigate(typeof(MainPage)); . So in App.xaml.cs the method App_BackRequested method try to get the Window.Current.Content as Frame for navigating, the back button will not work. 因此,在App.xaml.cs ,方法App_BackRequested方法尝试将Window.Current.Content as Frame获取Window.Current.Content as Frame用于导航的Window.Current.Content as Frame ,后退按钮将不起作用。

The solution is provided by the demo in the thread you reference, to add the BackRequested event handle in the page which defined the SplitView. 演示程序在您引用的线程中提供了该解决方案,以在定义SplitView的页面中添加BackRequested事件句柄。 Update your code in SplitShellPage.xaml.cs as follows the back button will work. 按照以下步骤更新SplitShellPage.xaml.cs的代码,后退按钮将起作用。

public SplitShellPage(Frame frame)
{
    this.InitializeComponent();
    NavigationCacheMode = NavigationCacheMode.Enabled;
    shell_splitview.Content = frame;
    (shell_splitview.Content as Frame).Navigate(typeof(MainPage));
    SystemNavigationManager.GetForCurrentView().BackRequested += SplitShellPage_BackRequested;
}

private void SplitShellPage_BackRequested(object sender, BackRequestedEventArgs e)
{
    Frame myFrame = shell_splitview.Content as Frame;
    if (myFrame.CanGoBack)
    {
        e.Handled = true;
        myFrame.GoBack();
    }
}

If I use the second line then SplitView doesn't work but back navigation works. 如果我使用第二行,则SplitView不起作用,但向后导航起作用。

In this situation, we even did not access the SplitShellPage , and didn't access the SplitView . 在这种情况下,我们甚至没有访问SplitShellPage ,也没有访问SplitView It is just a implemention of back button between two simple page. 它只是两个简单页面之间的后退按钮的实现。 It works and has noting relationship with the content of SplitView . 它的工作原理,并注意到与SplitView的内容的关系。

The key point for this issue is to clear which frame you are using for navigating now , rootFrame( Window.Current.Content ) or the SplitViewContent frame. 此问题的关键点是清除您现在用于导航的框架,rootFrame( Window.Current.Content )或SplitViewContent框架。 And navigating back with back button need the same frame. 而使用“后退”按钮向后导航需要相同的框架。

You can download the demo from the thread you referenced for further testing. 您可以从引用的线程下载演示,以进行进一步测试。 And more details please reference Back button navigation . 有关更多详细信息,请参考“ 后退”按钮导航

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM