MVVM + WPF - 为具有多个视图的 ViewModel 设计

Posted

技术标签:

【中文标题】MVVM + WPF - 为具有多个视图的 ViewModel 设计【英文标题】:MVVM + WPF - Design for ViewModel that has Multiple Views 【发布时间】:2019-03-11 01:01:33 【问题描述】:

我开发在各种信息亭上运行的 .NET/Winforms 应用程序。这些应用程序通常是全屏和触摸控制的。最近想用WPF技术和MVVM设计模式。

这些应用程序的可行设计是我有一个在其上切换屏幕(用户控件)的 MainForm(窗口)。因此,您只有一个“当前”屏幕,其中包含上一个、下一个等按钮(就像一个向导)。

大多数应用程序都有非常相似的逻辑。他们例如。需要从用户(一个屏幕)获取 OrderNumber(PIN,任何文本..),通过卡处理付款(第二个屏幕),... 不同应用程序的区别在于 GUI:图像、字体、颜色、显示器分辨率、按钮位置……

我的想法是编写典型的 ViewModel 并将它们放在公共库中。然后,特定的应用程序将为这些 ViewModel 提供它们的视图。然后,每个 ViewModel 将在整个应用程序生命周期内绑定到一个特定的 View。

例子:

库 Common.dll

包含典型的 ViewModel:ScreenGetTextViewModel、ScreenPayByCardViewModel、... (还包含 ViewModel 的默认视图)

应用 1:

引用 Common.dll 包含客户端 1 的视图:ScreenGetTextView、ScreenPayByCardView、...(这些视图绑定到 Common.dll 中的 ViewModel)

应用 2:

引用 Common.dll 包含客户端 2 的视图:ScreenGetTextView、ScreenPayByCardView、...(这些视图绑定到 Common.dll 中的 ViewModel)

在我看来,MVVM 是实现我的要求的正确方法,因为逻辑和 GUI 分离。

我的问题是如何在 WPF 中制作这个,使用什么,在哪里激发自己。我更喜欢没有 3rd 方 MVVM 工具包的简单解决方案(如果合理且可能的话)。

一些子问题/想法:

如何指定应绑定到特定 ViewModel 的 View?使用一些 ViewLocator?将“View”属性放到 ViewModel 中?

我更喜欢编写不与 WPF 耦合的 Common.dll,因为将来可能会出现 UWP 应用程序(如果可能的话)。

谢谢

【问题讨论】:

是的,这是可能的,而且 MVVM 很容易在没有框架的情况下完成。但是 ViewModel 属于(服务)一个 View,而不是相反。我认为你描述的是一个业务逻辑层,分享起来会更有意义。 【参考方案1】:

我只见过每个 ViewModel 的一个视图 - 所以如果有其他方法可以做到这一点,我会很感兴趣。

我会为每个视图使用一个 ViewModel,但每个 ViewModel 都继承自公共 ViewModel。

所以 Common.dll 将包含 ScreenPayByCardView,而应用程序 1 将包含继承自 ScreenPayByCardView 的 App1ScreenPayByCardView。这个 ViewModel 甚至可能不包含它自己的逻辑。

【讨论】:

【参考方案2】:

在 MVVM 方案中,您通常在视图的 XAML 代码中将视图模型引用为数据上下文。所以没有问题,你的 viewmodel 类的两个实例被两个不同的视图调用。如果您喜欢松散耦合进行单元测试,那么使用视图定位器是有意义的。

如果您的 common.dll 仅包含视图模型,则不应将其耦合到您的 WPF 视图。否则你违反了 MVVM 模式。

对 MVVM 来说相对较新,并且不得不接受框架的限制,我仍然喜欢 Laurent Bugnion 在 Pluralsight 上的 MVVMLight 课程(您的 MSDN 许可证中可能有 3 个月的免费订阅):https://www.pluralsight.com/courses/mvvm-light-toolkit-fundamentals

我还经常查看 MVVMLight 的代码以了解某些服务实现:https://github.com/lbugnion/mvvmlight/

对于第二个项目,我会立即使用 MVVMLight,因为它是开源的。但对于第一个项目来说,感受痛苦并理解为什么 MVVMLight(和其他框架)会发生某些变化是件好事。

希望有帮助!

【讨论】:

以上是关于MVVM + WPF - 为具有多个视图的 ViewModel 设计的主要内容,如果未能解决你的问题,请参考以下文章

具有多个图像的 WPF DataGrid RowDetailsTemplate (MVVM)

多个视图模型之间状态共享的具体示例(WPF MVVM)

带棱镜的 mvvm:从菜单项设置视图

在 WPF MVVM 中添加多个用户控件的最佳控件?

如何在MVVM中使用相同的ViewModel拥有多个视图?

WPF MVVM模式如何控制DataGrid的列隐藏和显示