我正在开发一个应该使用密码保护的Windows Phone 8应用程序。每次应用程序是lauchend或激活时,显示密码屏幕的最佳方法是什么?
我认为行动的中心点是带有Launch和Activation事件处理程序的App.xaml.cs。但是我怎样才能显示密码屏幕?
问题是,当应用程序启动或重新激活时,永远不知道将显示哪些页面。它是主页面或应用程序停用时最后显示的任何其他页面。
我试图拦截导航到第一页,取消它并显示密码页面:
// App.xaml.cs
private void InitializePhoneApplication() {
...
RootFrame.Navigating += HandleFirstNavigation;
...
}
private void HandleFirstNavigation(object sender, NavigatingCancelEventArgs e) {
RootFrame.Navigating -= HandleFirstNavigation;
e.Cancel = true;
RootFrame.Dispatcher.BeginInvoke(new Action(this.OpenPasscodePage));
}
private void OpenPasscodePage() {
RootFrame.Navigate(PasscodePageUri);
}
这有效,但只有当应用程序lauchend。当应用程序重新激活(休眠或逻辑删除)时,e.Cancel将被忽略。虽然调用了密码页面的导航,但会显示原始页面。
将导航密码页面从导航移动到导航也不值得:
private void InitializePhoneApplication() {
...
RootFrame.Navigated += PasscodePageAfterFirstNavigation;
...
}
private void PasscodePageAfterFirstNavigation(object sender, EventArgs e) {
RootFrame.Navigated-= PasscodePageAfterFirstNavigation;
RootFrame.Navigate(PasscodePageUri);
}
这似乎是某种竞争条件:有时显示密码页面,有时是原始页面。即使密码页面出现,这看起来很糟糕,因为在应用程序进一步导航到密码页面之前,首先会看到原始页面的一小部分。
两种解决方案都不起作用。知道实现这个的正确方法是什么?
编辑:与此同时,我尝试了第三种无效的解决方案。此解决方案使用Uri Mapper:
App.xaml.cs
public bool PasscodeWasConfirmed; private void Application_Launching(object sender, LaunchingEventArgs e) {
...
PasscodeWasConfirmed = false;
...
}
private void Application_Activated(object sender, ActivatedEventArgs e) {
...
PasscodeWasConfirmed = false;
...
}
public Uri InitialPageUri;
public bool ShouldRedirectToPasscodePage(Uri uri) {
if (PasswordWasConfirmend == false) {
InitialPageUri = uri;
return true;
}
return false;
}
UriMapper
public class AppUriMapper : UriMapperBase {
public override Uri MapUri(Uri uri) {
App app = (Application.Current as App);
if (app != null) {
if (app.ShouldRedirectToPasscodePage(uri))
return PasscodeQueryPage.PageUri;
}
// default
return uri;
}
}
PasscodePage
public partial class PasscodePage : PhoneApplicationPage {
...
private void PasscodeConfirmed() {
App app = (Application.Current as App);
app.PasscodeWasConfirmed = true;
NavigationService.Navigate(app.InitialPageUri);
}
}
Logic正在运行,没有任何问题,但在确认密码后,应用程序无法导航到InitialPageUri。 Uri Mapper被正确调用并返回InitialPageUri(不再重定向)。但是没有导航......
没有错误,异常或调试输出。什么都没发生......
使用Uri Mapper时的最大问题: 当应用程序从休眠状态重新激活时,没有可以映射或重定向的导航...
答案 0 :(得分:1)
(我编辑了以前的答案而不是添加新答案)
我花了一点时间试图找到解决方案,但我不明白为什么你的代码没有运行。
在我的情况下,如果我在App.xaml中做了这样的改变就足够了:
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
}
这适用于我的示例,该示例位于http://sdrv.ms/1ajH40E链接下
但是 - 我不能阻止用户在他退回按钮时看到最后一个屏幕并且正在选择返回哪个应用程序,然后眨眼他可以在离开应用程序之前看到最后一页。
我不知道点击MS按钮后是否可以改变这种行为:
windows phone change deactivated app image
第二次修改
好的 - 也许我已找到解决方案,为什么它有些工作,有时候不在你的代码中。在按下“开始”或“搜索”按钮后,应用程序可以转到两种情况:墓碑和非墓碑。返回后发生不同的事件。上面的代码适用于Tombstone案例,但不适用于非墓碑。要与你需要添加的第二个一起工作(因为页面没有再次初始化) - (当然它可以是不同的解决方案):
bool afterActivation = false;
private void Application_Activated(object sender, ActivatedEventArgs e)
{
afterActivation = true;
}
private void CheckForResetNavigation(object sender, NavigationEventArgs e)
{
// If the app has received a 'reset' navigation, then we need to check
// on the next navigation to see if the page stack should be reset
if (e.NavigationMode == NavigationMode.Reset)
RootFrame.Navigated += ClearBackStackAfterReset;
if (afterActivation)
{
afterActivation = false;
App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
}
}
请确保您在VS中的调试属性:项目 - >属性 - >调试 - >取消创建后的墓碑复选框。
你也可以在这里找到一些信息(如果你以前没见过):
http://blogs.msdn.com/b/ptorr/archive/2010/12/11/how-to-correctly-handle-application-deactivation-and-reactivation.aspx