为什么不等待此方法?
Why this method isn't being waited?
我有一个弹出窗口 window 使用 rg 插件弹出窗口扩展,应该使用消息中心发送一个布尔值,但调用此弹出窗口的方法从不等待结果。
你们可以在下面看到 DisplayAlert.cs 文件,它有一个显示模态 window 并使用消息中心接收布尔值的方法:
using Rg.Plugins.Popup.Extensions;
using Xamarin.Forms;
using System.Threading.Tasks;
namespace MasterDetailPageNavigation.XAML
{
public class Alerta
{
public Alerta(){}
public class Retorno
{
public bool valor { get; set; }
}
public bool retorno;
public async Task<bool> ShowAlert(string tipo, string titulo, string msg, string btnconfirm, string btncancel)
{
await App.Current.MainPage.Navigation.PushPopupAsync(
new DisplayAlert(tipo, titulo, msg, btnconfirm, btncancel)
);
MessagingCenter.Subscribe<Retorno>(this, "DisplayAlert", (value) =>
{
retorno = value.valor;
});
return retorno;
}
}
}
这是弹出式 ContentPage 的隐藏代码,正如我所说,消息中心必须 return 是真还是假:
using Xamarin.Forms;
using Rg.Plugins.Popup.Pages;
using Rg.Plugins.Popup.Extensions;
namespace MasterDetailPageNavigation.XAML
{
public partial class DisplayAlert : PopupPage
{
public DisplayAlert(string tipo, string titulo, string msg,string btnconfirm=null,string btncancel=null)
{
InitializeComponent();
switch (tipo)
{
case "ok":
XIcon.Text = "\uf058";
XIcon.TextColor = Color.FromHex("#009570");
break;
case "error":
XIcon.Text = "\uf06a";
XIcon.TextColor = Color.FromHex("#FF0000");
break;
case "confirm":
XIcon.Text = "\uf059";
XIcon.TextColor = Color.FromHex("#2181DF");
XBotoes.IsVisible = true;
XOk.IsVisible = false;
XConfirmar.Text = btnconfirm != null ? btnconfirm : XConfirmar.Text;
XCancelar.Text = btncancel != null ? btncancel : XCancelar.Text;
break;
}
XTitulo.Text = titulo;
XMsg.Text = msg;
}
void XOk_Clicked(System.Object sender, System.EventArgs e)
{
Navigation.PopPopupAsync();
}
public class Retorno
{
public bool valor { get; set; }
}
void XConfirmar_Clicked(System.Object sender, System.EventArgs e)
{
MessagingCenter.Send(new Retorno() { valor = true }, "DisplayAlert");
}
void XCancelar_Clicked(System.Object sender, System.EventArgs e)
{
MessagingCenter.Send(new Retorno() { valor = false }, "DisplayAlert");
}
}
}
最后,在主要部分 window,我调用并等待方法:
Alerta alerta = new Alerta();
// IT SHOULD AWAIT HERE BUT DON'T
bool opt = await alerta.ShowAlert("confirm", "Do you confirm?", "Message asking for confirmation","Exit","Continue here");
if (opt) //it's always false
{
Application.Current.Properties.Clear();
await Application.Current.SavePropertiesAsync();
Application.Current.MainPage = new Login();
}
我在哪里做错了或错过了什么?
在等待调用委托时使用 TaskCompletionSource
和 return 任务。
public class Alerta {
public Task<bool> ShowAlert(string tipo, string titulo, string msg, string btnconfirm, string btncancel) {
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
var popup = new DisplayAlert(tipo, titulo, msg, btnconfirm, btncancel) {
TaskSource = tcs
};
//show popup
App.Current.MainPage.Navigation.PushPopupAsync(popup);
return tcs.Task; //task to be awaited
}
}
但这需要一些重构
public partial class DisplayAlert : PopupPage {
public DisplayAlert(string tipo, string titulo, string msg,string btnconfirm=null,string btncancel=null) {
InitializeComponent();
switch (tipo) {
case "ok":
XIcon.Text = "\uf058";
XIcon.TextColor = Color.FromHex("#009570");
break;
case "error":
XIcon.Text = "\uf06a";
XIcon.TextColor = Color.FromHex("#FF0000");
break;
case "confirm":
XIcon.Text = "\uf059";
XIcon.TextColor = Color.FromHex("#2181DF");
XBotoes.IsVisible = true;
XOk.IsVisible = false;
XConfirmar.Text = btnconfirm != null ? btnconfirm : XConfirmar.Text;
XCancelar.Text = btncancel != null ? btncancel : XCancelar.Text;
break;
}
XTitulo.Text = titulo;
XMsg.Text = msg;
}
public TaskCompletionSource<bool> TaskSource { get; set; }
void XOk_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
}
void XConfirmar_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
TaskSource.SetResult(true);
}
void XCancelar_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
TaskSource.SetResult(false);
}
}
我有一个弹出窗口 window 使用 rg 插件弹出窗口扩展,应该使用消息中心发送一个布尔值,但调用此弹出窗口的方法从不等待结果。
你们可以在下面看到 DisplayAlert.cs 文件,它有一个显示模态 window 并使用消息中心接收布尔值的方法:
using Rg.Plugins.Popup.Extensions;
using Xamarin.Forms;
using System.Threading.Tasks;
namespace MasterDetailPageNavigation.XAML
{
public class Alerta
{
public Alerta(){}
public class Retorno
{
public bool valor { get; set; }
}
public bool retorno;
public async Task<bool> ShowAlert(string tipo, string titulo, string msg, string btnconfirm, string btncancel)
{
await App.Current.MainPage.Navigation.PushPopupAsync(
new DisplayAlert(tipo, titulo, msg, btnconfirm, btncancel)
);
MessagingCenter.Subscribe<Retorno>(this, "DisplayAlert", (value) =>
{
retorno = value.valor;
});
return retorno;
}
}
}
这是弹出式 ContentPage 的隐藏代码,正如我所说,消息中心必须 return 是真还是假:
using Xamarin.Forms;
using Rg.Plugins.Popup.Pages;
using Rg.Plugins.Popup.Extensions;
namespace MasterDetailPageNavigation.XAML
{
public partial class DisplayAlert : PopupPage
{
public DisplayAlert(string tipo, string titulo, string msg,string btnconfirm=null,string btncancel=null)
{
InitializeComponent();
switch (tipo)
{
case "ok":
XIcon.Text = "\uf058";
XIcon.TextColor = Color.FromHex("#009570");
break;
case "error":
XIcon.Text = "\uf06a";
XIcon.TextColor = Color.FromHex("#FF0000");
break;
case "confirm":
XIcon.Text = "\uf059";
XIcon.TextColor = Color.FromHex("#2181DF");
XBotoes.IsVisible = true;
XOk.IsVisible = false;
XConfirmar.Text = btnconfirm != null ? btnconfirm : XConfirmar.Text;
XCancelar.Text = btncancel != null ? btncancel : XCancelar.Text;
break;
}
XTitulo.Text = titulo;
XMsg.Text = msg;
}
void XOk_Clicked(System.Object sender, System.EventArgs e)
{
Navigation.PopPopupAsync();
}
public class Retorno
{
public bool valor { get; set; }
}
void XConfirmar_Clicked(System.Object sender, System.EventArgs e)
{
MessagingCenter.Send(new Retorno() { valor = true }, "DisplayAlert");
}
void XCancelar_Clicked(System.Object sender, System.EventArgs e)
{
MessagingCenter.Send(new Retorno() { valor = false }, "DisplayAlert");
}
}
}
最后,在主要部分 window,我调用并等待方法:
Alerta alerta = new Alerta();
// IT SHOULD AWAIT HERE BUT DON'T
bool opt = await alerta.ShowAlert("confirm", "Do you confirm?", "Message asking for confirmation","Exit","Continue here");
if (opt) //it's always false
{
Application.Current.Properties.Clear();
await Application.Current.SavePropertiesAsync();
Application.Current.MainPage = new Login();
}
我在哪里做错了或错过了什么?
在等待调用委托时使用 TaskCompletionSource
和 return 任务。
public class Alerta {
public Task<bool> ShowAlert(string tipo, string titulo, string msg, string btnconfirm, string btncancel) {
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
var popup = new DisplayAlert(tipo, titulo, msg, btnconfirm, btncancel) {
TaskSource = tcs
};
//show popup
App.Current.MainPage.Navigation.PushPopupAsync(popup);
return tcs.Task; //task to be awaited
}
}
但这需要一些重构
public partial class DisplayAlert : PopupPage {
public DisplayAlert(string tipo, string titulo, string msg,string btnconfirm=null,string btncancel=null) {
InitializeComponent();
switch (tipo) {
case "ok":
XIcon.Text = "\uf058";
XIcon.TextColor = Color.FromHex("#009570");
break;
case "error":
XIcon.Text = "\uf06a";
XIcon.TextColor = Color.FromHex("#FF0000");
break;
case "confirm":
XIcon.Text = "\uf059";
XIcon.TextColor = Color.FromHex("#2181DF");
XBotoes.IsVisible = true;
XOk.IsVisible = false;
XConfirmar.Text = btnconfirm != null ? btnconfirm : XConfirmar.Text;
XCancelar.Text = btncancel != null ? btncancel : XCancelar.Text;
break;
}
XTitulo.Text = titulo;
XMsg.Text = msg;
}
public TaskCompletionSource<bool> TaskSource { get; set; }
void XOk_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
}
void XConfirmar_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
TaskSource.SetResult(true);
}
void XCancelar_Clicked(System.Object sender, System.EventArgs e) {
Navigation.PopPopupAsync();
TaskSource.SetResult(false);
}
}