c# - DisplayAlert 之前的事件指示器

标签 c# xaml xamarin xamarin.forms xamarin.android

我的 Xamarin 应用程序中有一个通过 SMTP 服务器发送电子邮件的内容页面。

点击提交按钮发送电子邮件后,应用程序只会等待。在此等待期间,我想显示事件指示器或文本加载标签,以便用户在显示进程成功的 DisplayAlert 之前知道某些东西正在工作。

出于某种原因,ActivityIndi​​cator 和标签文本未显示。 也许我做错了什么。

XAML

<StackLayout x:Name="myPop" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" 
            AbsoluteLayout.LayoutFlags="All" BackgroundColor="#C0808080" Padding="5">

    <ContentView x:Name="input_box_overlay" 
    AbsoluteLayout.LayoutBounds="0, 0, 1, 1" 
    AbsoluteLayout.LayoutFlags="All" 
    Padding="5">

        <StackLayout Padding="20" BackgroundColor="White" 
                     HorizontalOptions="Center" VerticalOptions="Center"
                     HeightRequest="230" WidthRequest="230">
            <Label Text="Enter suggestion" TextColor="Black" FontSize="Medium"/>

            <StackLayout Padding="0, 10, 0, 0">
                <Editor x:Name="user_text" HeightRequest="100" Keyboard="Chat" BackgroundColor="#f7f8f9"/>
            </StackLayout>

            <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
                <Label Text="Submitting..." x:Name="load"/>
                <ActivityIndicator x:Name="indicator"/>
            </StackLayout>

            <StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand" HorizontalOptions="CenterAndExpand">
                <Button TextColor="White" Text="Cancel" Clicked="Cancel_Clicked" BackgroundColor="#C0808080"/>
                <Button TextColor="White" Text="Submit" Clicked="Submit_Clicked" BackgroundColor="#395368" />
            </StackLayout>


        </StackLayout>
    </ContentView>

</StackLayout>

Submit_Clicked 方法/事件的代码

private async void Submit_Clicked(object sender, EventArgs e)
{
    try
    {
       indicator.IsRunning = true;
       indicator.IsVisible = true;
       indicator.IsEnabled = true;
       load.IsVisible = true;

        MailMessage mail = new MailMessage();
        SmtpClient SmtpServer = new SmtpClient("smtp.sendgrid.net");
        mail.From = new MailAddress("email@domain.com");
        mail.To.Add("email@domain.com");
        mail.Subject = "Subject";
        mail.Body = user_msg;
        SmtpServer.Port = 25;
        SmtpServer.Credentials = new NetworkCredential("username", "password");
        SmtpServer.EnableSsl = true;
        ServicePointManager.ServerCertificateValidationCallback = delegate (object sendemail, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            return true;
        };
        SmtpServer.SendCompleted += (s, ev) => {
            indicator.IsRunning = false;
            indicator.IsVisible = false;
            indicator.IsEnabled = false;
            load.IsVisible = false;
        };
        SmtpServer.Send(mail);                        


        await DisplayAlert("Success", "Message Sent. Thank you.", "Ok");

        myPop.IsVisible = false;
        myPop.IsEnabled = false;
    }
    catch (Exception ex)
    {
        await DisplayAlert("Error", "Something went wrong. Please try again.", "ok");
        Console.WriteLine(ex.ToString());
    }
}

最佳答案

考虑保持代码异步,不要让它阻塞 UI,SmtpClient.Send

会发生这种情况

这是对提供的原始代码的重构,以允许非阻塞流

private async void Submit_Clicked(object sender, EventArgs e) {
    try {
        ToggleIndicator(true);
        await SendEmailAsync();
        ToggleIndicator(false);
        await DisplayAlert("Success", "Message Sent. Thank you.", "Ok");
        myPop.IsVisible = false;
        myPop.IsEnabled = false;
    } catch (Exception ex) {
        await DisplayAlert("Error", "Something went wrong. Please try again.", "ok");
        Console.WriteLine(ex.ToString());
    }
}

private void ToggleIndicator(bool show) {
    indicator.IsRunning = show;
    indicator.IsVisible = show;
    indicator.IsEnabled = show;
    load.IsVisible = show;
}

private async Task SendEmailAsync() {
    MailMessage mail = new MailMessage();
    mail.From = new MailAddress("email@domain.com");
    mail.To.Add("email@domain.com");
    mail.Subject = "Subject";
    mail.Body = user_msg;
    SmtpClient SmtpServer = new SmtpClient("smtp.sendgrid.net");
    SmtpServer.Port = 25;
    SmtpServer.Credentials = new NetworkCredential("username", "password");
    SmtpServer.EnableSsl = true;
    ServicePointManager.ServerCertificateValidationCallback = delegate (object sendemail, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) {
        return true;
    };
    await SmtpServer.SendMailAsync(mail);
}

虽然 XAML 看起来不错,但我还假设标签和指示符可见性最初是错误的

<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
    <Label Text="Submitting..." x:Name="load" IsVisible="False"/>
    <ActivityIndicator x:Name="indicator" IsVisible="False"/>
</StackLayout>

关于c# - DisplayAlert 之前的事件指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50205032/

相关文章:

c# - 我的标签未从 Form2 更新

c# - 使用 C#.net 从 Sharepoint Online 下载文件?

C# IE11 自动化 - 无法连接到打开的 IE 窗口

c# - 固定在 map 上(如 UI)

xaml - Windows 8 应用程序,更改 BackButtonStyle 的颜色

android - Xamarin 无法创建 Intent

c# - 从 C# 项目执行 .ps1 文件作为参数

c# - 我应该如何在文件事件触发器后面的 C# 代码中引用自定义控件?

ios - 我可以使用 Visual Studio 自动增加 Info.plist 文件中的 CFBundleVersion 值吗?

xaml - 在Xamarin.Forms中的XAML中使用资源文件