我一直在玩弄哪里放"你确定吗?" 在我的MVVM WPF应用程序中输入提示.
我倾向于认为这些纯粹是View的一部分.如果ViewModel公开了一个DeleteCommand,那么我希望该命令立即删除.
要将这些提示集成到ViewModel中,它必须公开一个单独RequestDeleteCommand的DeletePromptItem属性来绑定提示,并且还可以兼作显示提示的触发器.
即使这样,也没有什么能阻止单元测试DeleteCommand直接调用,除非我在ViewModel中放置特定的逻辑来要求DeletePromptItem匹配作为参数提供的项目DeleteCommand.
但是,这对我来说只是看起来像ViewModel中的噪音.提示更像是一个用户界面问题,以防止错误点击等.对我来说,这表明它应该在视图中,确认提示调用DeleteCommand.
有什么想法吗?
Jon*_*Jon 16
该提示应该肯定不会视图模型的一部分,但这并不一定意味着最好的解决方案是硬编码他们在查看(尽管这是一个非常合理的第一种方法).
我知道有两种方法可以减少View和ViewModel之间的耦合:使用交互服务,以及触发交互请求.两者都在这里解释得很好; 你可能想看看.
一般的想法是,您抽象异步交互是如何完成的,并使用与基于事件的逻辑更相似的东西,同时允许ViewModel表示它希望作为操作的一部分与用户交互 ; 最终结果是您可以记录此交互并对其进行单元测试.
编辑:我应该补充一点,我已经在原型项目中探索了使用Prism 4和交互请求,我对结果非常满意(有了一些框架代码,你甚至可以指定在特定的交互请求中完全发生的事情) XAML!).
但是,这对我来说只是看起来像ViewModel中的噪音.提示更像是一个用户界面问题,以防止错误点击等.对我来说,这表明它应该在视图中,确认提示调用DeleteCommand.
我同意; 这样的提示应该在视图中处理,因为最终视图是用户看到和交互的内容,而不是视图模型.一旦您的视图获得了用户确认DeleteCommand应该调用的信息,请继续并在视图模型中调用它.
我看待它的方式,单元测试与用户交互并没有任何关系,除非你正在测试视图本身.
在我看来,提示用户包括两部分:
第2部分显然不属于ViewModel.
但第1部分确实属于那里.
为了实现这种分离,我使用了ViewModel可以使用的服务,我可以为其提供特定于我所处环境的实现(WPF,Silverlight,WP7).
这导致代码如下:
interface IMessageBoxManager
{
MessageBoxResult ShowMessageBox(string text, string title,
MessageBoxButtons buttons);
}
class MyViewModel
{
IMessageBoxManager _messageBoxManager;
// ...
public void Close()
{
if(HasUnsavedChanges)
{
var result = _messageBoxManager.ShowMessageBox(
"Unsaved changes, save them before close?",
"Confirmation", MessageBoxButtons.YesNoCancel);
if(result == MessageBoxResult.Yes)
Save();
else if(result == MessageBoxResult.Cancel)
return; // <- Don't close window
else if(result == MessageBoxResult.No)
RevertUnsavedChanges();
}
TryClose(); // <- Infrastructure method from Caliburn Micro
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法不仅可以用来显示消息框,还可以显示其他窗口,如本答案中所述.
| 归档时间: |
|
| 查看次数: |
9077 次 |
| 最近记录: |