SplitView 和后退按钮导航 - UWP - C#
SplitView and Back Button Navigation - UWP - C#
我目前正在 UWP 环境中学习 C#。我有一个测试应用程序,它有一些问题,如 .
中所述
但是我的代码和上面的页面有点不同。
我的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();
}
}
}
}
如果我使用 Window.Current.Content = new SplitShellPage(rootFrame);
代替 Window.Current.Content = rootFrame;
,则 SplitView
有效,但后退按钮不起作用。如果我使用第二行,则 SplitView
不起作用,但后退导航有效。
我什至尝试将启动页面设置为 SplitView
页面 rootFrame.Navigate(typeof(SplitShellPage), e.Arguments);
,但这会导致应用程序在运行时停止并且应用程序无法启动。
其他页面代码如下:
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;
}
}
}
我在 google 上搜索时发现的这种工作方法使 NavigationPane
在所有页面中工作,并且在没有 Back Navigation
的情况下在所有页面中工作。
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));
}
}
}
我在 google 上做了一些搜索,但没有任何意义,因为他们使用了一些其他方法,事情变得更加复杂。
请让我知道我在这里做错了什么以及如何改正。谢谢。
P.S。让我知道是否还需要共享 XAML
文件。
If I use Window.Current.Content = new SplitShellPage(rootFrame); as in place of Window.Current.Content = rootFrame; the SplitView works but the back button does not work
在这种情况下,您当前使用的框架是shell_splitview.Content
。
因为您正在使用此代码导航 (shell_splitview.Content as Frame).Navigate(typeof(MainPage));
。所以在 App.xaml.cs
方法 App_BackRequested
方法中尝试获取 Window.Current.Content as Frame
用于导航,后退按钮将不起作用。
您参考的中的demo提供了解决方案,在定义SplitView的页面中添加BackRequested
事件句柄。更新 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.
在这种情况下,我们甚至没有访问SplitShellPage
,也没有访问SplitView
。它只是两个简单页面之间后退按钮的实现。它起作用并且与 SplitView
的内容有显着关系。
这个问题的关键点是清除您现在使用的导航框架,rootFrame(Window.Current.Content
) 或 SplitViewContent
框架。使用后退按钮向后导航需要相同的框架。
您可以从您引用的线程下载演示以进行进一步测试。更多详情请参考Back button navigation.
我目前正在 UWP 环境中学习 C#。我有一个测试应用程序,它有一些问题,如
中所述
但是我的代码和上面的页面有点不同。
我的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();
}
}
}
}
如果我使用 Window.Current.Content = new SplitShellPage(rootFrame);
代替 Window.Current.Content = rootFrame;
,则 SplitView
有效,但后退按钮不起作用。如果我使用第二行,则 SplitView
不起作用,但后退导航有效。
我什至尝试将启动页面设置为 SplitView
页面 rootFrame.Navigate(typeof(SplitShellPage), e.Arguments);
,但这会导致应用程序在运行时停止并且应用程序无法启动。
其他页面代码如下:
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;
}
}
}
我在 google 上搜索时发现的这种工作方法使 NavigationPane
在所有页面中工作,并且在没有 Back Navigation
的情况下在所有页面中工作。
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));
}
}
}
我在 google 上做了一些搜索,但没有任何意义,因为他们使用了一些其他方法,事情变得更加复杂。
请让我知道我在这里做错了什么以及如何改正。谢谢。
P.S。让我知道是否还需要共享 XAML
文件。
If I use Window.Current.Content = new SplitShellPage(rootFrame); as in place of Window.Current.Content = rootFrame; the SplitView works but the back button does not work
在这种情况下,您当前使用的框架是shell_splitview.Content
。
因为您正在使用此代码导航 (shell_splitview.Content as Frame).Navigate(typeof(MainPage));
。所以在 App.xaml.cs
方法 App_BackRequested
方法中尝试获取 Window.Current.Content as Frame
用于导航,后退按钮将不起作用。
您参考的BackRequested
事件句柄。更新 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.
在这种情况下,我们甚至没有访问SplitShellPage
,也没有访问SplitView
。它只是两个简单页面之间后退按钮的实现。它起作用并且与 SplitView
的内容有显着关系。
这个问题的关键点是清除您现在使用的导航框架,rootFrame(Window.Current.Content
) 或 SplitViewContent
框架。使用后退按钮向后导航需要相同的框架。
您可以从您引用的线程下载演示以进行进一步测试。更多详情请参考Back button navigation.