我处于一个棘手的位置。我有一个已发布的应用程序,并已收到崩溃报告。其中大多数是InvalidOperationException
。堆栈跟踪中的所有19个帧都显示内部函数,因此我无法确定引发它的函数。经过大量的调试,我认为InvalidOperation Exception是由我将导航重定向到Login页面的方式引起的。
基本操作是这样的。如果用户设置了密码,则导航到密码页面,否则导航到MainPage。代码如下
App()
{
// the usual code
RootFrame.Navigating += new NavigatingCancelEventHandler(RootFrame_Navigating);
}
void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (e.Uri.ToString().Contains("/RootPage.xaml") != true)
return;
CycleManager pCycMan = CycleManager.Instance;
e.Cancel = true;
RootFrame.Dispatcher.BeginInvoke(delegate
{
if (pCycMan.GetPasswordEnabled())
RootFrame.Navigate(new Uri("/PasswordPage.xaml", UriKind.Relative));
else
RootFrame.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
});
}
上面提到的RootPage在<App>
WMAppManifest.xml
标记中定义
<Tasks>
<DefaultTask Name="_default" NavigationPage="RootPage.xaml" />
</Tasks>
当我调试上面的代码时,我找到了与StackTrace相同的调用堆栈。有人能告诉我这是否是导航到其他主页的页面的正确方法?我在下面包含了StackTrace
"Frame Image Function Offset
0 coredll.dll xxx_RaiseException 19
1 mscoree3_7.dll 436488
2 mscoree3_7.dll 386545
3 mscoree3_7.dll 540936
4 TransitionStub 0
5 System.Windows.Navigation.NavigationService.Navigate 1580
6 System.Windows.Controls.Frame.Navigate 80
7 .__c__DisplayClass5._Application_Activated_b__3 136
8 mscoree3_7.dll 429164
9 mscoree3_7.dll 185803
10 mscoree3_7.dll 84423
11 System.Reflection.RuntimeMethodInfo.InternalInvoke 112
12 System.Reflection.RuntimeMethodInfo.InternalInvoke 1564
13 System.Reflection.MethodBase.Invoke 104
14 System.Delegate.DynamicInvokeOne 564
15 System.MulticastDelegate.DynamicInvokeImpl 84
16 System.Windows.Threading.DispatcherOperation.Invoke 80
17 System.Windows.Threading.Dispatcher.Dispatch 404
18 System.Windows.Threading.Dispatcher.OnInvoke 56
19 System.Windows.Hosting.CallbackCookie.Invoke 84"
感谢您耐心阅读这么长的问题。
答案 0 :(得分:1)
要控制导航,您可以像这样实现。
从app.xaml资源获取UriMapper,并将其分配给根框架
UriMapper mapper = Resources["mapper"] as UriMapper;
RootFrame.UriMapper = mapper;
然后根据需要更新映射器
if (IsPasswordSaved)
mapper.UriMappings[0].MappedUri = new Uri("/PasswordPage.xaml?method=UriMapper", UriKind.Relative);
else
mapper.UriMappings[0].MappedUri = new Uri("/MainPage.xaml?method=UriMapper", UriKind.Relative);
答案 1 :(得分:0)
Peter Torr在这里发表了一篇关于这件事的精彩文章 - http://blogs.msdn.com/b/ptorr/archive/2010/08/28/redirecting-an-initial-navigation.aspx?wa=wsignin1.0
HTH 鲁珀特。
答案 2 :(得分:0)
谢谢大家,我按照@ pan4321给出的提示稍作修改。
这就是我最终做到的。
我已将WMAppManifest
中的默认导航设置为名为RootPage.xaml的不存在页面
<Tasks>
<DefaultTask Name="_default" NavigationPage="RootPage.xaml" />
</Tasks>
App.xaml的<Application
标记
xmlns:UriMapper="clr-namespace:System.Windows.Navigation;assembly=Microsoft.Phone">
并在<Application.Resources
标记
<UriMapper:UriMapper x:Name="mapper">
<UriMapper:UriMapping Uri="/RootPage.xaml" />
</UriMapper:UriMapper>
在App()
内,我致电SetupUriMapper()
void SetupUriMapper()
{
// Get the UriMapper from the app.xaml resources, and assign it to the root frame
UriMapper mapper = Resources["mapper"] as UriMapper;
RootFrame.UriMapper = mapper;
//
CycleManager pCycMan = CycleManager.Instance;
bool isPasswordSet = pCycMan.GetPasswordEnabled();
// Update the mapper as appropriate
if (isPasswordSet)
mapper.UriMappings[0].MappedUri = new Uri("/PasswordPage.xaml", UriKind.Relative);
else
mapper.UriMappings[0].MappedUri = new Uri("/MainPage.xaml", UriKind.Relative);
}
现在为什么我将默认导航更改为“RootPage.xaml”而不是通常的MainPage.xaml,只是因为在导航到密码页面后,输入密码并单击确定后我无法导航到MainPage.xaml 。它保留在同一页面的PasswordPage内。
我发现网上遍布的答案很少,这就是我理解的方式。在检查条件后在PasswordPage上,如果它是真的,理想情况下应该导航到MainPage.xaml。但是,如果我们在WMAppManifest文件中将我们的默认页面设置为MainPage.xaml,则它将无法导航,因为它正在寻找用于导航的新Uri [NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
],并且我们的默认当前导航仍设置为MainPage.xaml。由于Uri没有变化,因此它保留在PasswordPage。但是如果我们将默认页面定义为RootPage,则在到达PasswordPage时,我们的导航Uri是MainPage,而我们的默认Uri是RootPage。
if (passwordBox1.Password == pCycMan.GetPassword())
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
希望这对某人有所帮助。如果我弄错了,请纠正我。