关于c#:UWP-MessageDialog在Windows Phone和平板电脑模式下使应用程序崩溃

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;
};
        }

当我在Application.UnhandledException事件处理程序中调用MessageDialog.ShowAsync时,我的UWP应用程序崩溃了,这是我搜索答案时的最高结果。

我通过在调用MessageDialog.ShowAsync之前设置UnhandledExceptionEventArgs.Handled = true解决了该问题。

这在另一个SO问题中得到了很好的证明,但是直到找到解决方案后我才找到答案,因为我没有意识到从Application.UnhandledException调用方法很重要。


没有任何方法可以完成您想要的-后退键处理程序需要立即回答(是否处理),但是对话框本质上是异步的。

当然,您可以选择在显示对话框之前将事件标记为Handled,但是如果用户说"是",则无法继续浏览。您当然可以终止应用程序,但这是一个坏主意(请参阅最后一段)

就是说,您通常不需要此对话框,因为在Windows 10中,退出某个应用程序不会终止该对话框,它只会切换到上一个应用程序(或"开始"菜单)。用户可以通过任务切换器(或再次启动它)简单地返回它。