任何时候都只能打开一个ContentDialog [英] Only a single ContentDialog can be open at any time

查看:70
本文介绍了任何时候都只能打开一个ContentDialog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我多次按下登录按钮,则会触发消息:异步操作未正确启动.任何时候都只能打开一个ContentDialog." (此处的延迟表示应用程序与服务器联系以查看用户是否有效所花费的时间.)

If I press my login button multiple times, it triggers the message: "An async operation was not properly started. Only a single ContentDialog can be open at any time." (The delay is there to represent the time it takes for the app to contact the server to see if the user is valid.)

如果我使用MessageDialog,一切正常,但是我想使用ContentDialog提供的额外自定义.

If I use MessageDialog everything works ok, but I want to use the extra customisation that ContentDialog provides.

链接没有帮助.下面的代码示例向我展示了如何使用它.

This link has not helped. My code example below shows me trying to use it.

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>

后面的代码:

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 borrowed from link mentioned above:

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

我在Button_Click()中添加了DoingStuff,以防止出现错误消息,但我认为必须有更好的方法:

I added DoingStuff to Button_Click(), which prevents the error message, but I think there must be a better way:

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

推荐答案

通常,启动登录方法时,需要同时启用登录按钮,以避免多次单击.并且您的解决方案也可用,直到在上一个对话框显示之前,该按钮才起作用.

In general, when you start the login method, you need to enable your login button at same time to avoid multiple click. And your solution is also available that the button will not work until the previous dialog showed.

我创建了新的ContentDialogMaker.有关更多信息,请参阅以下内容.

And I have created newContentDialogMaker. For more you could refer the following.

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

唯一的区别是ActiveDialog是在ActiveDialog_Closing事件处理程序方法中清空的.并且可以确保显示后将清除先前的对话框.因此,只有一个ContentDialog将同时打开.

The only difference is that the ActiveDialog was emptied in the ActiveDialog_Closing event handler method. And it could maker sure the previous dialog would be cleared after displayed. So, there is only a single ContentDialog will be open at same time.

这篇关于任何时候都只能打开一个ContentDialog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆