Reputation: 998
I have a content page that sends an email over an SMTP server in my Xamarin app.
On clicking the submit button to send the email, the app does nothing but waits. During this wait, I want to show an activity indicator or a Label of text loading, so the user knows something is working before showing a DisplayAlert that the process was successful.
For one reason or the other, the ActivityIndicator, and Label Text is not showing. Maybe am doing something wrong.
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>
Code for the Submit_Clicked
method/event
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 protected]");
mail.To.Add("[email protected]");
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());
}
}
Upvotes: 1
Views: 687
Reputation: 247088
Consider keeping the code async and not making it block the UI, which is what would happen with SmtpClient.Send
This is a refactoring of the original code provided to allow for a non-blocking flow
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 protected]");
mail.To.Add("[email protected]");
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);
}
While the XAML looks OK, I would also assume that the label and indicator visibility would be false initially
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Label Text="Submitting..." x:Name="load" IsVisible="False"/>
<ActivityIndicator x:Name="indicator" IsVisible="False"/>
</StackLayout>
Upvotes: 3