Wpf 避免小型窗口的MVVM/数据绑定?
我发现视图模型对于分割用户界面和业务逻辑代码非常有用。然而,我也有过这样的经历:对于小而简单的windows,视图模型类只是添加了大量额外的代码,有效地降低了可维护性,而不是提高了可维护性 让我给你一个简单的,真实的例子,我最近有:一个对话框窗口提供两个(固定文本)按钮和一个可定制的文本块Wpf 避免小型窗口的MVVM/数据绑定?,wpf,data-binding,mvvm,Wpf,Data Binding,Mvvm,我发现视图模型对于分割用户界面和业务逻辑代码非常有用。然而,我也有过这样的经历:对于小而简单的windows,视图模型类只是添加了大量额外的代码,有效地降低了可维护性,而不是提高了可维护性 让我给你一个简单的,真实的例子,我最近有:一个对话框窗口提供两个(固定文本)按钮和一个可定制的文本块 使用普通的老x:Name-基于代码隐藏的编程技术,这只需要几行代码(设置文本,通过返回值并关闭窗口来处理两次按钮点击)——干净简单 与上面的解决方案相比,使用“推荐方法”,即创建视图模型类(实现INotify
x:Name
-基于代码隐藏的编程技术,这只需要几行代码(设置文本,通过返回值并关闭窗口来处理两次按钮点击)——干净简单(因此,要么您没有遗漏任何内容,要么我遗漏了同样的内容。)您可以使用数据绑定,而无需定义视图模型,而且在大多数“小”窗口中,没有太多逻辑,因此您实际上不需要更改通知 只需设置DataContext=this,并将数据绑定到窗口类的属性 另一方面,命令没有好的简单版本,所以我只使用好的旧事件处理
(我还认为MVVM对于很多不太小的窗口来说是过分的,但在这一点上我显然是少数。)我做了类似的事情,但是在我只想要一个非常小的窗口来做一些非常基本的事情的情况下,我至少实现了一个接口并通过网关调用它,这样我就可以以可测试的方式调用它。大概是这样的: //例如。在viewmodel.cs或command.cs中
var sometextIwantUserToEnter = UIServices.GetMeSomethingThatCan().GetText();
我的窗口将实现IGetText,我用GetText方法在窗口本身中执行所有窗口显示和结果检查。这使窗口中的所有内容保持隔离,我可以断言服务是在我的测试中调用的
希望这是有意义的。我完全支持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; }
}
实现一次,然后使用继承来配置需要它的各种实例。从我的示例中可以看到,这允许您将更多的语义编码到类中
另请参见,并且--仅供参考--。您不必在视图模型类中实现
INotifyPropertyChanged
。只有在需要更改通知时才需要这样做,而对于简单对话框,则不需要这样做
我不能谈论VB的具体问题,但在C#中,产生的代码至少和它在窗口的代码中隐藏时一样简单和简洁——如果您尝试在不实现命令的情况下实现命令行为,通常更是如此。(“我将在这个属性设置器中将IsEnabled
设置为true
,以便在输入数据后启用OK按钮”,这是“just”一词被证明是个该死的谎言的句子之一。)
对此的反驳——“当然,但如果我不实现更改通知,那么当某个属性值发生更改时,我就不能执行X和Y操作”——削弱了您所构建的内容很简单的断言
我发现,总的来说,没有什么事情像我第一次开始时想象的那么简单。向视图模型类添加更改通知和命令要比从窗口的代码中重构视图模型类容易得多,这样我就可以向视图模型类添加更改通知和命令
最后,如果您在所有情况下都使用简单视图模型类来支持简单视图(只有一种情况除外),那么有一天,这一种情况会让您(或其他开发人员)吃一顿苦头。如果一致性的成本很低,那么在一致性方面还有很多话要说。听起来不错,尽管如果你坚持使用VB,代码仍然非常多:你的SmallDialogTask代码示例将有50多个LOC,并且缺少匿名方法会使定义命令有点麻烦(你不能只是在lambda表达式中捕获一个窗口引用来设置它的DialogResult,等等。)我急切地等待VB10。。。