Mvvm 暂停viewmodel进程以供用户输入

Mvvm 暂停viewmodel进程以供用户输入,mvvm,modal-dialog,design-patterns,Mvvm,Modal Dialog,Design Patterns,我一直在查看viewmodel问题中典型提升对话框的视图示例,注意到3个主要解决方案: 使用附加行为 使用中介模式 使用服务 但我有点陷入困境,很难找到一个适合我的问题空间的解决方案,这是一个非常简单的文件复制问题: 我的viewmodel正在处理复制文件列表的循环 当目标位置已经存在文件时,我需要启动一个模式对话框,以获得替换确认 vm需要等待并接收确认后才能继续 模态对话框实际上不是一个新窗口,而是我的主窗口中的一个隐藏覆盖,正如感谢Ronald! 我大部分时间都在那里,但最大的困难是: -

我一直在查看viewmodel问题中典型提升对话框的视图示例,注意到3个主要解决方案:

使用附加行为 使用中介模式 使用服务 但我有点陷入困境,很难找到一个适合我的问题空间的解决方案,这是一个非常简单的文件复制问题:

我的viewmodel正在处理复制文件列表的循环 当目标位置已经存在文件时,我需要启动一个模式对话框,以获得替换确认 vm需要等待并接收确认后才能继续 模态对话框实际上不是一个新窗口,而是我的主窗口中的一个隐藏覆盖,正如感谢Ronald! 我大部分时间都在那里,但最大的困难是: -如何在viewmodel中暂停循环以等待输入 -如何将输入返回到循环中的viewmodel,以便它可以继续

到目前为止,我倾向于服务解决方案,因为它似乎是一个直接的方法调用,返回的结果是vm必须等待的。但是,这确实意味着服务需要直接绑定到视图,以便使元素可见


如果有人可以发布一些简单的代码,直接处理这个问题,我和网络将非常高兴!谢谢

例如,您有一个名为IDialogService的服务,该服务具有以下接口:

public interface IDialogService
{
   bool ConfirmAction(string title, string confirmationText);
}
正如您所提到的,为了使服务能够显示实际的对话框,它需要对将显示实际覆盖元素的视图进行引用。但与其直接引用视图,我更喜欢通过接口引用它。我们将其称为ICanShowDialog,它将具有以下成员:

public interface ICanShowDialog
{
   void ShowDialog(object dialogContent);
   void HideDialog();
}
此界面将由拥有对话框覆盖的视图实现,例如主窗口

现在是有趣的部分:在显示对话框时暂停代码执行。首先,我建议您不要使用覆盖元素,而是尽可能使用普通窗口。那你就不会有这个问题了。您可以设置对话框窗口的样式,使其看起来像覆盖元素。 无论如何,如果仍要使用覆盖元素,则可以执行以下技巧来暂停代码执行:

以下是IDialogService接口的confirmation方法的伪代码:

public bool ConfirmAction(string title, string confirmationText)
{
   ConfirmationDialogView dialogView = new ConfirmationDialogView(title, confirmationText);

   DialogShower.ShowDialog(dialogView); // DialogShower is of type ICanShowDialog

   while (!dialogView.ResultAvailable)
   {
      DispatcherUtils.DoEvents();
   }

   DialogShower.HideDialog();

   return dialogView.Result;
}
以下是从此处获取的DispatcherUtils.DoEvents的代码:

但我必须警告你。使用DoEvents可能会导致一些由内部dispatcher循环引起的细微错误

作为在显示对话框时暂停代码执行的替代方法,您可以使用回调:

public interface IDialogService
{
   void ConfirmAction(string title, string confirmationText, Action<bool> dialogResultCallback);
}

但使用起来并不方便。

谢谢Pavlo,我希望避免使用可能导致细微错误的解决方案:
public interface IDialogService
{
   void ConfirmAction(string title, string confirmationText, Action<bool> dialogResultCallback);
}