UWP - MessageDialog crashes the app on Windows Phone and tablet mode
在Windows 10 Universal应用程序中,我想在按下后退按钮时显示MessageDialog。
我页面的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible; SystemNavigationManager.GetForCurrentView().BackRequested += GamePage_BackRequested; } private async void GamePage_BackRequested(object sender, BackRequestedEventArgs e) { var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?"); dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes")); dialog.Commands.Add(new Windows.UI.Popups.UICommand("No")); var result = await dialog.ShowAsync(); } |
当我在"本地计算机"中放置应用程序时,对话框会很好地显示。 但是,当我将Windows设置为"平板电脑模式"时,或者在Windows Phone上尝试使用它时,ShowAsync方法会使应用程序崩溃(没有错误)。
为什么应用程序崩溃?
问题似乎是应该从UI线程调用" dialog.ShowAsync()"方法。
这就是我解决的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | private void GamePage_BackRequested(object sender, BackRequestedEventArgs e) { e.Handled = true; Frame rootFrame = Window.Current.Content as Frame; if (rootFrame.CanGoBack) { var d = dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ShowConfirmationDialog(rootFrame)); } } public async void ShowConfirmationDialog(Frame rootFrame) { var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?"); dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes") { Id = 0 }); dialog.Commands.Add(new Windows.UI.Popups.UICommand("No") { Id = 1 }); var result = await dialog.ShowAsync(); if (result != null && result.Label =="Yes") { rootFrame.GoBack(); } } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; SystemNavigationManager.GetForCurrentView().BackRequested += GamePage_BackRequested; } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); SystemNavigationManager.GetForCurrentView().BackRequested -= GamePage_BackRequested; } |
您应该处理回退请求; e.handled = true;
1 2 3 4 5 6 7 8 9 10 | private async void GamePage_BackRequested(object sender, BackRequestedEventArgs e) { e.handled = true; var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?"); dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes")); dialog.Commands.Add(new Windows.UI.Popups.UICommand("No")); var result = await dialog.ShowAsync(); } |
您应该添加onnavigatedfrom方法取消注册该事件,否则它将触发两次!
1 2 3 4 5 6 7 8 | protected override void OnNavigatedFrom(NavigationEventArgs e) { if (gb.DetectPlatform() == Platform.WindowsPhone) HardwareButtons.BackPressed -= HardwareButtons_BackPressed; elde SystemNavigationManager.GetForCurrentView().BackRequested -= GamePage_BackRequested; }; } |
当我在
我通过在调用
这在另一个SO问题中得到了很好的证明,但是直到找到解决方案后我才找到答案,因为我没有意识到从
没有任何方法可以完成您想要的-后退键处理程序需要立即回答(是否处理),但是对话框本质上是异步的。
当然,您可以选择在显示对话框之前将事件标记为
就是说,您通常不需要此对话框,因为在Windows 10中,退出某个应用程序不会终止该对话框,它只会切换到上一个应用程序(或"开始"菜单)。用户可以通过任务切换器(或再次启动它)简单地返回它。