Caliburn.Micro Screen.CanClose()和MessageDialog()。ShowAsync()

时间:2014-07-12 20:21:03

标签: caliburn.micro windows-phone-8.1 windows-rt

我目前正在为我的Windows Phone 8.1项目(通用应用程序)使用Caliburn.Micro 2.0,我在用户点击MessageDialog按钮后有条件取消关闭页面时遇到问题。

似乎Caliburn在离开CanClose()方法后关闭了页面,而不是等待在异步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);  
  }
}

2 个答案:

答案 0 :(得分:2)

我目前唯一的解决方案是设置一个带有标志的字段,指示页面是否可以关闭。在用户尝试导航回来时,我告诉Caliburn中止关闭并显示确认对话框。当我得到结果时,我将标志设置为true并手动导航回来。这会导致另一次调用CanClose,但这次我将回调设置为true并跳过对话框部分。

我不太喜欢这个解决方案,但这只是我设法解决这个问题的方法。

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:我没有直接在我的ViewModel中使用MessageDialog,我正在使用弹出窗口的对话框服务接口。我在这里用它来证明这个问题。

答案 1 :(得分:0)

虽然未设置增强CanClose,但我的方法是利用Navigating event解决此问题&#39;

如果用户可以轻松处理 GoBack(),但就我而言,还有很多导航选项。所以,我找到解决问题的唯一方法如下所述:

public MyViewModel(INavigationService navigationService)
{
    _navigationService = navigationService;
    _navigationService.Navigating += OnGoBack;
}

private async void OnGoBack(object sender, NavigatingCancelEventArgs e)
{
    e.Cancel = true;

    var dlg = new MessageDialog("Close?", "Confirmation"); //Dialog for demo purpose only!
    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) return;
    _navigationService.Navigating -= OnGoBack;
    if (e.NavigationMode == NavigationMode.Back)
        _navigationService.GoBack();
    else
    {
        var myViewModel = Type.GetType($"YourNameSpaceViewModels.{e.SourcePageType.Name}Model");
        _navigationService.NavigateToViewModel(myViewModel);
    }
}

阐释:

$"YourNameSpaceViewModels.{e.SourcePageType.Name}Model"
在这里,我获得了我的课程的完整路径,用户想要转到

所以,我导航到它_navigationService.NavigateToViewModel(myViewModel);