I'm currently using Caliburn.Micro 2.0 for my Windows Phone 8.1 project (Universal App) and I'm having problem with conditionally cancelling page close after user clicks a MessageDialog button.
It seems that Caliburn closes page after leaving CanClose() method, not waiting for the callback which is called after async MessageDialog.
public class MyViewModel: Screen
{
public override async void CanClose(Action<bool> callback)
{
MessageDialog dlg = new MessageDialog("Close?","Confirmation");
dlg.Commands.Add(new UICommand() { Id = 0, Label = "Yes" });
dlg.Commands.Add(new UICommand() { Id = 1, Label = "No" });
var result = await dlg.ShowAsync();
callback((int)result.Id == 0);
}
}
The only solution I have at the moment is set a field with a flag indicating if the page can be closed. On the user attempt to navigate back I tell Caliburn to abort the close and I display the confirmation dialog. When I get the result I set the flag to true and navigate back manually. This causes another call to CanClose, but this time I set the callback to true and skip the dialog part.
I don't like this solution much, but it is only way I managed to solve this problem.
private bool canClose = false;
public override async void CanClose(Action<bool> callback)
{
callback(canClose);
if (!canClose)
{
MessageDialog dlg = new MessageDialog("Close?","Confirmation");
dlg.Commands.Add(new UICommand() { Id = 0, Label = "Yes" });
dlg.Commands.Add(new UICommand() { Id = 1, Label = "No" });
var result = await dlg.ShowAsync();
if ((int)result.Id == 0)
{
canClose = true;
navigationService.GoBack();
}
}
}
PS: I don't use MessageDialog directly in my ViewModel, I'm using a dialog service interface for popups. I just used it here to demonstrate the issue.