Xamarin Forms AppShell 如何 return 到上一页
Xamarin Forms AppShell How return to previous page
我看到很多关于此类主题的帖子,但 none 似乎适用于我的问题。我没有导航页面,我有一个汉堡菜单——所以 Push/PopAsync() 似乎不是答案。而且我不想转到特定页面,我想返回上一页(无论它是什么)所以 GoToAsync() 似乎不是答案。
用于 Android 的 Xamarin 应用程序和 iOS 未来某个地方的 UWP。下面的问题描述是Android特有的;它在 UWP 上的工作方式略有不同。
我想在汉堡菜单中放置一个帮助条目,它将把用户带到默认浏览器中的帮助页面。汉堡包菜单似乎只转到应用程序页面,所以我定义了一个“虚拟”视图页面,显示“正在加载...”并在其 OnAppearing() 方法中发出 Browser.OpenAsync() ,这非常有效。问题在于,用户希望在单击“帮助” 之前,“后退”按钮会将他或她带到他们所在的页面 。我尝试了几件事。我已经接近以下内容,但它不能正常工作:
在我的每个其他视图的 OnAppearing() 中,我调用了一个方法,将 Current.MainPage.CurrentItem 的值保存在静态中。然后在 OpenAsync() 之后的帮助页面中,我将 Current.MainPage.CurrentItem 设置为帮助页面之前最后一页的设置。
Console.WriteLine("#### HelpPage loading Web Help");
_ = State.DisplayHelpPage(this, "MainHelp"); // _ = await Browser.OpenAsync(uri, blo);
Console.WriteLine("#### HelpPage returning to previous page");
State.ReloadPreviousPage(); // Current.MainPage).CurrentItem = lastFlyoutItem;
差不多可以了。第一次单击汉堡菜单中的帮助时,我得到
#### HelpPage loading Web Help
#### HelpPage returning to previous page
#### HelpPage loading Web Help
#### HelpPage returning to previous page
网页加载完美。但是,当我单击“后退”按钮时,它会再次显示。很明显我的OnAppearing()方法已经被驱动了两次,我不明白。
如果我再次单击“后退”按钮,我将返回应用程序中的上一页,就像我想要的那样。下次我在 Hamburger 菜单中单击“帮助”时,它会将我带到没有网页的虚拟“查看”页面。显然,我的 OnAppearing() 根本没有被驱动。但在那之后它完美地工作。我可以转到任何应用程序页面,然后单击菜单中的帮助。我得到了网页,然后“后退”按钮将我带回到应用程序和页面。在 UWP 中,浏览器当然不会加载到应用程序视图之上,而且我似乎每次都看到它被加载两次。
所以...我应该做些什么不同的事情?为什么我的 OnAppearing() 被驱动了两次,然后就完全不被驱动了……然后就如我所料?
这个答案有几个部分:
- 将上一页放到导航堆栈中。这是通过拦截路由“//HelpPage”并将其替换为不是 Shell.
的子路由来完成的
- 记住“FakePageVisible”,所以我们知道在 OnResume 中执行“PopAsync”,当应用 returns 来自浏览器时。
- (可选)“进入”标志可防止进入浏览器两次。
App.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override void OnResume()
{
if (HelpPage.FakePageVisible) {
HelpPage.FakePageVisible = false;
var shell = MainPage as AppShell;
if (shell != null) {
shell.Navigation.PopAsync();
}
}
}
}
AppShell.xaml.cs:
public partial class AppShell : Xamarin.Forms.Shell
{
public AppShell()
{
InitializeComponent();
// Define a route that isn't a child of Shell.
Routing.RegisterRoute("Help2", typeof(HelpPage));
}
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
if (args.Current != null) {
if (args.Source == ShellNavigationSource.ShellItemChanged) {
if (args.Target.Location.OriginalString == "//HelpPage") {
// Cancel the original route.
args.Cancel();
Device.BeginInvokeOnMainThread(() => {
// Used by the next OnAppearing.
HelpPage.Entering = true;
// Go there by a route that isn't a child of Shell.
// Doing so, pushes our previous location on to Navigation stack.
Shell.Current.GoToAsync("Help2");
});
}
}
}
}
}
HelpPage.xaml.cs:
public partial class HelpPage : ContentPage
{
public static bool Entering;
public static bool FakePageVisible;
protected override void OnAppearing
{
// Make sure this only happens once (just in case).
if (Entering) {
Entering = false;
FakePageVisible = true;
Xamarin.Essentials.Browser.OpenAsync("https://aka.ms/xamarin-quickstart");
}
}
}
对于一个简单的演示,此代码通过 HelpPage 中的静态变量进行通信。根据您的情况重新考虑因素。
我看到很多关于此类主题的帖子,但 none 似乎适用于我的问题。我没有导航页面,我有一个汉堡菜单——所以 Push/PopAsync() 似乎不是答案。而且我不想转到特定页面,我想返回上一页(无论它是什么)所以 GoToAsync() 似乎不是答案。
用于 Android 的 Xamarin 应用程序和 iOS 未来某个地方的 UWP。下面的问题描述是Android特有的;它在 UWP 上的工作方式略有不同。
我想在汉堡菜单中放置一个帮助条目,它将把用户带到默认浏览器中的帮助页面。汉堡包菜单似乎只转到应用程序页面,所以我定义了一个“虚拟”视图页面,显示“正在加载...”并在其 OnAppearing() 方法中发出 Browser.OpenAsync() ,这非常有效。问题在于,用户希望在单击“帮助” 之前,“后退”按钮会将他或她带到他们所在的页面 。我尝试了几件事。我已经接近以下内容,但它不能正常工作:
在我的每个其他视图的 OnAppearing() 中,我调用了一个方法,将 Current.MainPage.CurrentItem 的值保存在静态中。然后在 OpenAsync() 之后的帮助页面中,我将 Current.MainPage.CurrentItem 设置为帮助页面之前最后一页的设置。
Console.WriteLine("#### HelpPage loading Web Help");
_ = State.DisplayHelpPage(this, "MainHelp"); // _ = await Browser.OpenAsync(uri, blo);
Console.WriteLine("#### HelpPage returning to previous page");
State.ReloadPreviousPage(); // Current.MainPage).CurrentItem = lastFlyoutItem;
差不多可以了。第一次单击汉堡菜单中的帮助时,我得到
#### HelpPage loading Web Help
#### HelpPage returning to previous page
#### HelpPage loading Web Help
#### HelpPage returning to previous page
网页加载完美。但是,当我单击“后退”按钮时,它会再次显示。很明显我的OnAppearing()方法已经被驱动了两次,我不明白。
如果我再次单击“后退”按钮,我将返回应用程序中的上一页,就像我想要的那样。下次我在 Hamburger 菜单中单击“帮助”时,它会将我带到没有网页的虚拟“查看”页面。显然,我的 OnAppearing() 根本没有被驱动。但在那之后它完美地工作。我可以转到任何应用程序页面,然后单击菜单中的帮助。我得到了网页,然后“后退”按钮将我带回到应用程序和页面。在 UWP 中,浏览器当然不会加载到应用程序视图之上,而且我似乎每次都看到它被加载两次。
所以...我应该做些什么不同的事情?为什么我的 OnAppearing() 被驱动了两次,然后就完全不被驱动了……然后就如我所料?
这个答案有几个部分:
- 将上一页放到导航堆栈中。这是通过拦截路由“//HelpPage”并将其替换为不是 Shell. 的子路由来完成的
- 记住“FakePageVisible”,所以我们知道在 OnResume 中执行“PopAsync”,当应用 returns 来自浏览器时。
- (可选)“进入”标志可防止进入浏览器两次。
App.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override void OnResume()
{
if (HelpPage.FakePageVisible) {
HelpPage.FakePageVisible = false;
var shell = MainPage as AppShell;
if (shell != null) {
shell.Navigation.PopAsync();
}
}
}
}
AppShell.xaml.cs:
public partial class AppShell : Xamarin.Forms.Shell
{
public AppShell()
{
InitializeComponent();
// Define a route that isn't a child of Shell.
Routing.RegisterRoute("Help2", typeof(HelpPage));
}
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
if (args.Current != null) {
if (args.Source == ShellNavigationSource.ShellItemChanged) {
if (args.Target.Location.OriginalString == "//HelpPage") {
// Cancel the original route.
args.Cancel();
Device.BeginInvokeOnMainThread(() => {
// Used by the next OnAppearing.
HelpPage.Entering = true;
// Go there by a route that isn't a child of Shell.
// Doing so, pushes our previous location on to Navigation stack.
Shell.Current.GoToAsync("Help2");
});
}
}
}
}
}
HelpPage.xaml.cs:
public partial class HelpPage : ContentPage
{
public static bool Entering;
public static bool FakePageVisible;
protected override void OnAppearing
{
// Make sure this only happens once (just in case).
if (Entering) {
Entering = false;
FakePageVisible = true;
Xamarin.Essentials.Browser.OpenAsync("https://aka.ms/xamarin-quickstart");
}
}
}
对于一个简单的演示,此代码通过 HelpPage 中的静态变量进行通信。根据您的情况重新考虑因素。