我遇到了同样的问题:
我不是C#或WP专家,所以请耐心等待。
问题:当我使用辅助磁贴(“/MainPage.xaml?id=XX”)恢复应用时,我会看到前一个实例的简要视图(已经恢复)和然后MainPage再次初始化,创建一个新实例。实际上,该应用程序在向我展示之前打开的内容后从头开始加载。
这显然是不受欢迎的行为。我想使用现有实例来执行我的任务。
尝试1 :
使用e.Cancel = true;
取消导航到MainPage.xaml:
(使用官方Fast App Resume sample中的App.xaml.cs代码来确定应用的启动方式)
...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
// This block will run if the previous navigation was a relaunch
wasRelaunched = false;
if (e.Uri.ToString().Contains("="))
{
// This block will run if the launch Uri contains "=" (ex: "id=XX") which
// was specified when the secondary tile was created in MainPage.xaml.cs
sessionType = SessionType.DeepLink;
e.Cancel = true; // <======================== Here
// The app was relaunched via a Deep Link.
// The page stack will be cleared.
}
}
...
问题 :这样做,我的OnNavigatedTo事件处理程序永远不会触发,因此我的查询字符串永远不会被解析。
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
String navId;
if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
{
if (NavigationContext.QueryString.TryGetValue("id", out navId))
{
MessageBox.Show(navId.ToString()); // Not reached
}
}
...
尝试2 :
使用e.Cancel = true;
取消导航到MainPage.xaml, AND 将Uri传递给MainPage中的方法:
// App.xaml.cs
...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
// This block will run if the previous navigation was a relaunch
wasRelaunched = false;
if (e.Uri.ToString().Contains("="))
{
// This block will run if the launch Uri contains "=" (ex: "id=XX") which
// was specified when the secondary tile was created in MainPage.xaml.cs
sessionType = SessionType.DeepLink;
e.Cancel = true;
MainPage.GoToDeepLink(e.Uri); // <======================== Here
// The app was relaunched via a Deep Link.
// The page stack will be cleared.
}
}
...
// MainPage.xaml.cs
public static void GoToDeepLink(Uri uri) // <======================== Here
{
// Convert the uri into a list and navigate to it.
string path = uri.ToString();
string id = path.Substring(path.LastIndexOf('=') + 1);
MyList list = App.ViewModel.ListFromId(Convert.ToInt32(id));
pivotLists.SelectedItem = list;
}
问题 :我收到错误, pivotLists 是非静态的,因此需要对象引用。我认为为了使这个工作,我需要创建一个新的MainPage实例(MainPage newMainPage = new MainPage();
)并调用newMainPage.pivotLists.SelectedItem = list;
- 但我不知道如何使用newMainPage而不是现有的/替换它......或者如果那是我想要/不会引起进一步的问题/并发症。
我不知道解决这个问题的方法是什么,我可能会走向完全错误的方向。如果可以,请使用代码示例简单地保留所有建议,我仍在学习。
感谢您的帮助。
答案 0 :(得分:1)
似乎当您从辅助磁贴重新打开应用程序时,它会被重新激活并创建新的MainPage实例(即使之前的运行中有一个)。如果我理解正确的话,我就设法做了这样的事情:
在app.xaml.cs中:
我添加了一个变量,指示在从辅助磁贴导航后是否应该返回到上一个MainPage - 它需要是静态的,因为我想从MainPage访问它
public static bool returnPage = false;
在RootFrame_Navigating中我将此变量设置为true:
// ...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
// This block will run if the previous navigation was a relaunch
wasRelaunched = false;
returnPage = true;
// ...
在ClearBackStackAfterReset中 - 在返回时阻止删除旧页面:
// ...
if (e.NavigationMode != NavigationMode.New || returnPage)
return;
// ...
在MainPage.cs中:
我已经改变了一个小构造函数,因为我不希望看到一个新的页面闪烁:
public MainPage()
{
if (!App.returnPage)
InitializeComponent();
}
在MainPage中我也是从辅助磁贴传递的变量 - 它也是静态的,因为我只需要它的一个实例:
private static string navId = "";
诀窍的核心 - OnNavigatedTo:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (App.returnPage)
{
App.returnPage = false;
NavigationContext.QueryString.TryGetValue("id", out navId);
NavigationService.GoBack();
}
else if (e.NavigationMode != NavigationMode.Reset)
{
// normal navigation
}
}
它的工作原理如下:
当您从辅助磁贴激活它时,很少发生这种情况:
1。首先使用NavigationMode.Reset导航到您的上一页 - 我们对它不感兴趣,所以我关闭它 - 什么都不应该发生 2.然后程序尝试创建MainPage的新实例,但returnPage为true,并且由于if语句,InitializeComponent将不会运行。就在此之后,在OnNavigatedTo中,程序保存传递的查询字符串并导航回以前的MainPage实例 - 从上次运行开始 3.最后我们使用NavigationMode.Back导航到正确的MainPage,我们将查询字符串保存在静态变量中。
你必须意识到两件事:首先 - 可能它可能很少重建(我不确定是否需要重新启动等等) - 你需要调试它并看看你可以摆脱什么。第二 - 您可能需要使用Tombstone案例测试您的应用程序。
希望这有帮助。