我发现视图模型对于拆分用户界面和业务逻辑代码非常有用。但是,我也体验过,对于小而简单的窗口,视图模型类只需添加大量额外代码,有效地降低了可维护性,而不是改进它。
让我给你一个我最近有过的简单,真实的例子:一个对话窗口,提供两个(固定文本)按钮和一个可自定义的文本块。
使用普通的基于x:Name
的代码隐藏编程技术,这是几行代码的问题(设置文本,通过返回值并关闭窗口来处理两次按钮单击) - 干净简单。
执行“推荐方式”,即创建视图模型类(实现INotifyPropertyChanged或继承DependencyObject)和定义命令需要大量的代码与上面的解决方案相比(特别是因为没有简洁的方法在VB中定义“局部变量+属性+引发PropertyChanged” - 使解决方案的可读性降低,更容易出错。
所以,目前我正在使用实用的方法在“普通旧x:名称”和视图模型之间进行选择。然而,丰富的博客/论坛帖子声称视图模型应该一直使用,这让我想知道我是否忽略了某些东西。
我忽略了什么吗?
答案 0 :(得分:4)
我全部都是MVVM,但是您所描述的窗口可以实现一次,然后根据需要填充,当您想要打开它时。所以ViewModel可能如下所示:
public SmallDialogTask
{
string Title { get; set; }
string Text { get; set; }
string AcceptButtonLabel { get; set; }
string RejectButtonLabel { get; set; }
Command AcceptCommand { get; }
Command RejectCommand { get; }
}
实现一次并使用继承来配置您需要它的各种实例。正如您在我的示例中所看到的,这允许您将更多语义编码到您的类中。
另请参阅DRY,my question about MVVM dialogs和 - 仅供参考 - my blog post about MVVM。
答案 1 :(得分:3)
您可以在不定义视图模型的情况下使用数据绑定 - 并且在大多数“小”窗口中没有模糊逻辑 - 因此您实际上不需要更改通知。
只需将DataContext = this和data-bind设置为窗口类的属性即可。
另一方面,命令没有很好的简单版本,所以我只使用旧的事件处理。
(我也认为MVVM对很多不那么小的窗口来说太过分了,但我显然在那个窗口中占少数几个)
答案 2 :(得分:1)
我也这样做。
小对话框和快速选择或信息消息只是以最简单的方式完成。我尽量不要用不必要的模式来复杂化。主要的应用程序窗口和更大的东西通常都是用MVVM完成的。
(所以要么你没有错过任何东西,要么我错过了同样的事情。)
答案 3 :(得分:1)
我做了类似的事情然而在我只想要一个非常小的窗口做一些非常基本的事情我至少实现一个接口并通过网关调用它以便我可以以可测试的方式调用它。像这样:
//例如在viewmodel.cs或command.cs
中
var sometextIwantUserToEnter = UIServices.GetMeSomethingThatCan().GetText();
我的窗口将实现IGetText,我在GetText方法中对窗口本身进行所有Window显示和结果检查。这样可以使窗口中的所有内容保持隔离状态,并且我可以断言在我的测试中调用了该服务。
希望这是有道理的。
答案 4 :(得分:1)
您不必在视图模型类中实现INotifyPropertyChanged
。如果您需要更改通知,则只需执行此操作,对于简单对话框,您不需要更改通知。
我不能谈论特定于VB的问题,但在C#中,结果的代码至少与它存在于窗口的代码隐藏中一样简单和简洁 - 如果你尝试的话,通常会更多在不执行命令的情况下实现命令行为。 (“我只是在此属性设置器中将IsEnabled
设置为true
,以便在输入数据后启用”确定“按钮,”是“just”结果为“just”的句子之一是个该死的谎言。)
对此的反驳 - “当然,但如果我没有实施变更通知,那么当某些东西改变了财产价值时,我就无法做X和Y” - 削弱了你正在构建的内容很简单的说法。
我发现一般来说,没有什么比我想象的那样简单。向视图模型类添加更改通知和命令要比从窗口的代码隐藏重构视图模型类要容易得多,以便我可以向其添加更改通知和命令。
最后,如果您使用简单的视图模型类来支持所有情况下的简单视图而不是一个,那么有一天这个案例会让你(或其他一些开发人员)咬一口。如果一致性成本很低,那么可以说有很多一致性。