Programmatically dismiss a MessageDialog

2019-07-05 20:56发布

问题:

On Windows Phone 8.1, how to programmatically dismiss a MessageDialog after the ShowAsync call?

I’ve tried calling IAsyncInfo.Close(), it just throws an InvalidOperationException "An illegal state change was requested".

I’ve tried calling IAsyncInfo.Cancel(). The dialog stays visible, the only result - after I tap the “Close” button, TaskCancelledException is marshaled to the awaiting routine.

Update: exact behavior depends on the sequence of the calls.

  1. If IAsyncOperation.Cancel() is invoked before await theTask - await keyword throws TaskCancelledException at once. However, the dialog stays visible.
  2. If await theTask; is invoked before IAsyncOperation.Cancel(), the dialog stays visible, but unlike #1, await continues waiting for a button to be tapped. Only then a TaskCanceledException is raised.

BTW, my scenario is #2: I need to be able to close message dialogs after some routine is already waiting for its completion.

回答1:

This is how it's done in RT. Save that ShowAsync Task and you can cancel that later.

    private IAsyncOperation<IUICommand> dialogTask;
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageDialog dlg = new MessageDialog("This will close after 5 seconds");
        try
        {
            dialogTask = dlg.ShowAsync();
        }
        catch (TaskCanceledException)
        {
            //this was cancelled
        }

        DispatcherTimer dt = new DispatcherTimer();
        dt.Interval = TimeSpan.FromSeconds(5);
        dt.Tick += dt_Tick;
        dt.Start();
    }

    void dt_Tick(object sender, object e)
    {
        (sender as DispatcherTimer).Stop();
        dialogTask.Cancel();
    }

Notice the ShowAsync() is not awaited. Instead is saved to a task which can be cancelled. Sadly I tried this on WP and it didn't work.