windows windows-8 windows-runtime winrt-xaml messagedialog

windows - MessageDialog ShowAsync arroja una excepción accessdenied en el segundo diálogo



windows-8 windows-runtime (5)

Estoy intentando implementar try again / cancel cuadro de diálogo en Windows 8. El cuadro de diálogo se muestra bien la primera vez, pero al hacer clic en try again y fallar de nuevo, obtengo una excepción de acceso denegado al llamar a ShowAsync. No sé por qué, pero a veces es extraño, el código funciona bien y no obtengo la excepción cuando pongo puntos de corte. realmente despistado aquí

aquí está el código.

async void DismissedEventHandler(SplashScreen sender, object e) { dismissed = true; loadFeeds(); } private async void loadFeeds() { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { try { RSSDataSource rssDataSource = (RSSDataSource)App.Current.Resources["RSSDataSource"]; if (rssDataSource != null) { await rssDataSource.DownloadFeeds(); await rssDataSource.GetFeedsAsync(); } AdDataSource ads = (AdDataSource)App.Current.Resources["AdDataSource"]; if (ads != null) { await ads.DownloadAds(); } rootFrame.Navigate(typeof(HomePageView)); Window.Current.Content = rootFrame; } catch { ShowError(); } }); } async void ShowError() { // There was likely a problem initializing MessageDialog msg = new MessageDialog(CONNECTION_ERROR_MESSAGE, CONNECTION_ERROR_TITLE); // Add buttons and set their command handlers msg.Commands.Add(new UICommand(COMMAND_LABEL_RETRY, new UICommandInvokedHandler(this.CommandInvokedHandler))); msg.Commands.Add(new UICommand(COMMAND_LABEL_CLOSE, new UICommandInvokedHandler(this.CommandInvokedHandler))); // Set the command to be invoked when a user presses ''ESC'' msg.CancelCommandIndex = 0; await msg.ShowAsync(); } /// <summary> /// Callback function for the invocation of the dialog commands /// </summary> /// <param name="command">The command that was invoked</param> private void CommandInvokedHandler(IUICommand command) { string buttonLabel = command.Label; if (buttonLabel.Equals(COMMAND_LABEL_RETRY)) { loadFeeds(); } else { // Close app Application.Current.Exit(); } }


Bien, encontré una solución rápida,

definir un varialble clase IAsyncOperation

IAsyncOperation<IUICommand> asyncCommand = null;

y configurarlo en el método ShowAsync de MessageDialog

asyncCommand = msg.ShowAsync();

En el controlador de comando para retry / try again, compruebe si asyncCommand no es nulo y cancele la última operación si es necesario

if(asyncCommand != null) { asyncCommand.Cancel(); }

Por favor, déjenme si hay un mejor enfoque para esto.


Estuve enfrentando este mismo problema hace algunos días, y lo resuelvo esperando el ShowAsync y luego hago la llamada recursiva que abre el MessageDialog nuevamente.

public async void ShowDlg(){ Action cmdAction = null; var msgDlg = new MessageDialog("Content.", "Title"); msgDlg.Commands.Add(new UICommand("Retry", (x) => { cmdAction = () => ShowDlg(); })); msgDlg.Commands.Add(new UICommand("Cancel", (x) => { cmdAction = () => <Action associated with the cancel button>; })); msgDlg.DefaultCommandIndex = 0; msgDlg.CancelCommandIndex = 1; await msgDlg.ShowAsync(); cmdAction.Invoke(); }

¡Espero que esto ayude!



Llego tarde a la fiesta, pero aquí hay una manera en la que siempre puede esperar el resultado del cuadro de diálogo, así como no tener que preocuparse por llamar a demasiados en una fila:

Primero defina una variable y método estático en su aplicación:

private static IAsyncOperation<IUICommand> messageDialogCommand = null; public async static Task<bool> ShowDialog(MessageDialog dlg) { // Close the previous one out if (messageDialogCommand != null) { messageDialogCommand.Cancel(); messageDialogCommand = null; } messageDialogCommand = dlg.ShowAsync(); await messageDialogCommand; return true; }

Ahora puede pasar cualquier cuadro de diálogo y esperar siempre la ejecución. Es por eso que esto devuelve un bool en lugar de vacío. No tendrá que preocuparse por las colisiones entre los múltiplos. ¿Por qué no hacer que este método acepte una cadena? Debido al título y a los controladores de comando Sí / No que puede asignar al cuadro de diálogo específico que está utilizando.

Invocar como:

await App.ShowDialog(new MessageDialog("FOO!"));

o

var dlg = new MessageDialog("FOO?", "BAR?"); dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(YesHandler))); dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler(NoHandler))); await App.ShowDialog(dlg);


Otra solución:

private bool _messageShowing = false; // ... if (!_messageShowing) { _messageShowing = true; var messageDialog = new MessageDialog("Example"); // ... "messageDialog" initialization Task<IUICommand> showMessageTask = messageDialog.ShowAsync().AsTask(); await showMessageTask.ContinueWith((showAsyncResult) => { _messageShowing = false; }); }