覆盖WP8导航 - 在PhoneApplicationPage中崩溃

Ana*_*tts 5 windows-phone windows-phone-8

我正在尝试做一些可以说是坏主意的事情,但我认为这仍然是可能的.我试图覆盖WP8如何处理后退按钮并自己实现它.我认为如果我:

计划

  1. 只在整个应用程序中创建一个"框架"和"页面"
  2. 总是处理PhoneApplicationPage.BackKeyPress自己,除非他们即将退出应用程序.

Repro

这是一个崩溃的示例项目

代码

..然后它应该工作.但是,我的尝试被Windows Phone挫败了.这是代码:

// This basically happens on PhoneApplicationService.OnLaunched
_viewModelChanged.StartWith(ViewModel).Where(x => x != null).Subscribe(vm => {
    var page = default(IViewFor);
    var frame = RootVisual as PhoneApplicationFrame;

    // Find the initial PhoneApplicationPage for the app
    page = RxApp.GetService<IViewFor>("InitialPage");

    // Depending on how we're being signalled (i.e. if this is cold start 
    // vs. resume), we need to create the PhoneApplicationFrame ourselves
    if (frame == null) {
        frame = new PhoneApplicationFrame() {
            Content = page,
        };
    }

    page.ViewModel = vm;
    var pg = page as PhoneApplicationPage;
    if (pg != null) {
        pg.BackKeyPress += (o, e) => {
            if (ViewModel.Router.NavigationStack.Count <= 1 ||
                ViewModel.Router.NavigateBack.CanExecute(null)) {
                return;
            }

            e.Cancel = true;
            ViewModel.Router.NavigateBack.Execute(null);
        };
    }

    // Finally, set Application.RootVisual
    RootVisual = frame;
});
Run Code Online (Sandbox Code Playgroud)

这很好用,直到这段代码执行完毕后,框架排队的DispatcherItem崩溃了app:

System.NullReferenceException occurred
Message: A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.Phone.ni.dll
Microsoft.Phone.ni.dll!Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)   Unknown
Microsoft.Phone.ni.dll!Microsoft.Phone.Controls.PhoneApplicationPage.Microsoft.Phone.Controls.IPhoneApplicationPage.InternalOnNavigatedFromX(System.Windows.Navigation.NavigationEventArgs e)   Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.RaiseNavigated(object content, System.Uri uri, System.Windows.Navigation.NavigationMode mode, bool isNavigationInitiator, Microsoft.Phone.Controls.IPhoneApplicationPage existingContentPage, Microsoft.Phone.Controls.IPhoneApplicationPage newContentPage) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.CompleteNavigation(System.Windows.DependencyObject content, System.Windows.Navigation.NavigationMode mode)   Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(System.IAsyncResult result) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(System.AsyncCallback userCallback, System.Windows.Navigation.PageResourceContentLoader.PageResourceContentLoaderAsyncResult result) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad.AnonymousMethod__0(object args)    Unknown
[Native to Managed Transition]  
mscorlib.ni.dll!System.Delegate.DynamicInvokeImpl(object[] args)    Unknown
System.Windows.ni.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
System.Windows.ni.dll!System.Windows.Threading.Dispatcher.Dispatch(System.Windows.Threading.DispatcherPriority priority)    Unknown
System.Windows.ni.dll!System.Windows.Threading.Dispatcher.OnInvoke(object context)  Unknown
System.Windows.ni.dll!System.Windows.Hosting.CallbackCookie.Invoke(object[] args)   Unknown
System.Windows.RuntimeHost.ni.dll!System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(System.IntPtr pHandle, int nParamCount, System.Windows.Hosting.NativeMethods.ScriptParam* pParams, System.Windows.Hosting.NativeMethods.ScriptParam* pResult)   Unknown
Run Code Online (Sandbox Code Playgroud)

Ana*_*tts 5

所以,我已经解决了这个 - 我的代码是有问题的,因为我没有弄清楚WP8是如何工作的:)这是我现在理解的,这也可能是错的,但我还是会写的

您的WP8应用程序如何初始化:

  1. 操作系统通过重新水化App.xaml.cs来创建您的App类
  2. 这意味着,您的构造函数会运行,并且作为其中的一部分,您将创建一个 PhoneApplicationFrame
  3. 创建一个PhoneApplicationFrame似乎设置了一个全局静态变量(同样的事情发生PhoneApplicationService在App.xaml中创建,它设置PhoneApplicationService.Current).
  4. NavigationService然后尝试通过资源字符串(即'/MainPage.xaml')重新创建XAML视图.它会重新创建以前被逻辑删除的那个,或者如果没有,它会默认为WMAppManifest中的那个(这是我不理解的部分).
  5. PhoneApplicationFrame.Navigated由NavigationService调用 - 这是你可以实际开始做的事情,包括最重要的是,设置Application.RootVisual,它将发送Loading ...屏幕
  6. PhoneApplicationService.LaunchedPhoneApplicationService.Activated最终触发,一旦基本上所有设置后,根据您的应用程序是如何唤醒.