Si j'appuie sur mon bouton de connexion plusieurs fois, cela déclenche le message: "Une opération asynchrone n'a pas été correctement démarrée. Un seul ContentDialog peut être ouvert à tout moment." (Le délai est là pour représenter le temps nécessaire à l'application pour contacter le serveur pour voir si l'utilisateur est valide.)

Si j'utilise MessageDialog, tout fonctionne correctement, mais je souhaite utiliser la personnalisation supplémentaire fournie par ContentDialog.

Ceci le lien n'a pas aidé. Mon exemple de code ci-dessous montre que je tente de l'utiliser.

XAML:

<Page
    x:Class="DuckTracker.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DuckTracker"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Height="20">Name:</TextBlock>
    <TextBox Grid.Row="0" Grid.Column="1" Height="20"></TextBox>
    <Button Click="Button_Click" Grid.Row="2" VerticalAlignment="Bottom">Login</Button>
    </Grid>
</Page>

Code derrière:

using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace DuckTracker
{

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            bool canLogin = await CanLogin(); 

            if (canLogin == false)
            {
                try
                {
                     await AlertWithMessages("Fail", "Could not log in!", "ok");

                }
                catch (Exception ex)
                {

                    var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "Error");
                    await dialog.ShowAsync();
                }

            }
        }

        public async Task AlertWithMessages(string title, string msg, string confirm)
        {
            ContentDialog dialog = new ContentDialog()
            {
                Title = title,
                Content = msg,
                PrimaryButtonText = confirm
            };

            await ContentDialogMaker.CreateContentDialogAsync(dialog, true);

        }

        public async Task<bool> CanLogin()
        {
            await Task.Delay(1000);

            return false;
        }
    }
}

Code emprunté au lien mentionné ci-dessus:

using System;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;

namespace DuckTracker
{
    public static class ContentDialogMaker
    {
        public static async void CreateContentDialog(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }
        public static async Task CreateContentDialogAsync(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }

        static async Task CreateDialog(ContentDialog Dialog, bool awaitPreviousDialog)
        {
            if (ActiveDialog != null)
            {
                if (awaitPreviousDialog)
                {
                    await DialogAwaiter.Task;
                    DialogAwaiter = new TaskCompletionSource<bool>();
                }
                else ActiveDialog.Hide();
            }
            ActiveDialog = Dialog;
            ActiveDialog.Closed += ActiveDialog_Closed;
            await ActiveDialog.ShowAsync();
            ActiveDialog.Closed -= ActiveDialog_Closed;
        }

        public static ContentDialog ActiveDialog;
        static TaskCompletionSource<bool> DialogAwaiter = new TaskCompletionSource<bool>();
        private static void ActiveDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args) { DialogAwaiter.SetResult(true); }
    }
}

J'ai ajouté DoingStuff à Button_Click (), ce qui empêche le message d'erreur, mais je pense qu'il doit y avoir un meilleur moyen:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    if (DoingStuff == false)
    {
        DoingStuff = true;

        bool canLogin = await CanLogin();

        if (canLogin == false)
        {
            try
            {

                await AlertWithMessages("Fail", "Could not log in!", "ok");

            }
            catch (Exception ex)
            {

                var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "Error");
                await dialog.ShowAsync();
            }

        }

        DoingStuff = false;
    }
}
2
Gail Foad 23 mai 2018 à 14:07

4 réponses

Meilleure réponse

En général, lorsque vous démarrez la méthode de connexion, vous devez activer votre bouton de connexion en même temps pour éviter plusieurs clics. Et votre solution est également disponible que le bouton ne fonctionnera pas jusqu'à ce que la boîte de dialogue précédente s'affiche.

Et j'ai créé un nouveau ContentDialogMaker. Pour plus d'informations, vous pouvez consulter ce qui suit.

public static class ContentDialogMaker
{
    public static async void CreateContentDialog(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }
    public static async Task CreateContentDialogAsync(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }

    static async Task CreateDialog(ContentDialog Dialog, bool awaitPreviousDialog)
    {
        if (ActiveDialog != null)
        {
            if (awaitPreviousDialog)
            {
                ActiveDialog.Hide();
            }
            else
            {
                switch (Info.Status)
                {
                    case AsyncStatus.Started:
                        Info.Cancel();
                        break;
                    case AsyncStatus.Completed:
                        Info.Close();
                        break;
                    case AsyncStatus.Error:

                        break;
                    case AsyncStatus.Canceled:

                        break;
                }
            }
        }
        ActiveDialog = Dialog;
        ActiveDialog.Closing += ActiveDialog_Closing;
        Info = ActiveDialog.ShowAsync();
    }
    public static IAsyncInfo Info;
    private static void ActiveDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args)
    {
        ActiveDialog = null;
    }

    public static ContentDialog ActiveDialog;
}

La seule différence est que ActiveDialog a été vidé dans la méthode du gestionnaire d'événements ActiveDialog_Closing. Et cela pourrait être sûr que la boîte de dialogue précédente serait effacée après son affichage. Donc, il n'y a qu'un seul ContentDialog qui sera ouvert en même temps.

2
Nico Zhu - MSFT 24 mai 2018 à 08:34

Désactivez le bouton pendant que vous gérez le clic.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    if (sender is Button button)
    {
        button.IsEnabled = false;
    }

    … handle button click

    if (sender is Button button2)
    {
        button2.IsEnabled = true;
    }
}
0
Michael S. Scherotter 23 mai 2018 à 15:08
using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;




namespace DuckTracker
{

public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
bool canLogin = await CanLogin();

if (canLogin == false)
{
try
{
await AlertWithMessages("Fail", "Could not log in!", "ok");

}
catch (Exception ex)
{

var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "Error");
await dialog.ShowAsync();
}

}
}

public async Task AlertWithMessages(string title, string msg, string confirm)
{
ContentDialog dialog = new ContentDialog
{
Title = title,
Content = msg,
PrimaryButtonText = confirm
};


ContentDialogResult result = await dialog.ShowAsync();


}

public async Task<bool> CanLogin()
{
await Task.Delay(1000);

return false;
}
}
}
0
Gosha 9 déc. 2019 à 17:49

Essayez ceci avant d'ouvrir la boîte de dialogue suivante.

ContentDialogMaker.ActiveDialog?.Hide();
// Show new Dialog here.
1
William Bradley 23 mai 2018 à 23:37