如何在Windows Forms应用程序中实现MVC模式?

69

我并不经常开发桌面/Windows Forms应用程序,但我想到可能在使用MVC(模型视图控制器)模式进行Windows Forms .NET开发时会有一些好处。

是否有人在Windows Forms中实现了MVC?如果是这样,您对设计有什么建议?


2
如果您能在问题中添加更多详细信息,可能会获得更好的回答。例如,您的模型组件是基于什么的?是基于数据库还是永久文件或其他什么?我假设视图部分将比较简单,只需要一些表单,但也许您也想说说这个?细节能够使问题更容易解决。 - Onorio Catenacci
6个回答

44

我过去使用类似的东西,叫做Model-View-Presenter

[注意:该文章曾经在网上可以找到。现在需要下载CHM文件,然后查看文件属性并点击取消阻止,这样才能打开CHM并找到文章。感谢微软!叹气]

窗体是视图,我为其创建了一个IView接口。所有处理都在Presenter中进行,它只是一个类。窗体创建一个新的Presenter,并将自己作为Presenter的IView传递。这样,在测试时可以传入一个虚假的IView,然后从Presenter向其发送命令并检测结果。

如果我要使用完整的Model-View-Controller,我会这样做:

  • 窗体是视图。它向模型发送命令,引发控制器可以订阅的事件,并订阅模型的事件。
  • 控制器是一个订阅视图事件并向视图和模型发送命令的类。
  • 模型引发视图订阅的事件。

这将符合经典的MVC图表。最大的缺点是,使用事件时可能很难确定谁订阅了什么。 MVP模式使用方法而不是事件(至少我实现的方式是如此)。当窗体/视图引发事件(例如单击某个按钮)时,窗体只需调用Presenter中的方法来运行它的逻辑。视图和模型根本没有任何直接关系;它们都必须通过Presenter进行操作。


2
每个人都有自己喜欢的MVC/MVP配方。我的建议是先浏览http://martinfowler.com/eaaDev/ModelViewPresenter.html,然后再做决定。我曾经在TDD yahoogroup上写过一个例子,名为Example-of-test-driving-a-UI-Application,如果你有时间可以看看。 - Gishu
我认为这就是用户Gishu所指的线程。那些文件需要登录Yahoo才能访问 - 因为我没有账户,所以无法确定它们是否仍然存在。 - surfmuggle
1
迄今为止我读过的最简单、最完整的答案之一。我的想法与你所陈述的基本相同,但我并没有找到适用于MVC的通用配方。大多数应用程序都有特定的需求,我发现大多数情况下控制器会与视图合并 - 在表单类中的事件处理程序。 - Joel
模型-视图-控制器的链接已经失效。 - Whirlwind

21

实际上,Windows Forms实现了一种“自由风格”的MVC,就像一些电影采用一些糟糕的“自由风格”诠释一些经典著作一样(例如《罗密欧与朱丽叶》)。

我并不是说Windows Forms的实现很差,它只是......不同。

如果你使用Windows Forms和适当的面向对象编程技术,还可能使用类似EntitySpaces的ORM来访问数据库,那么你可以这样说:

  1. ORM/OOP架构是模型(Model)。
  2. 表单(Form)是视图(Views)。
  3. 事件处理程序是控制器(Controller)。

虽然将视图(View)和控制器(Controller)表示为相同的对象会使得代码从表示分离变得更加困难(在派生自Microsoft.Windows.Forms.Form的类中没有简单的方法来插入"GTK+ view")。

如果你足够小心,你能做到的是将表单(Form)代码完全与控制器/模型代码分离,只在事件处理程序中编写与GUI相关的内容,其他所有业务逻辑都在一个单独的类中。在这种情况下,如果你想使用GTK+编写另一个视图层(View layer),你只需要重新编写GUI代码。


16

Windows Forms并非从头开始设计用于使用MVC。您有两个选择。

首先,您可以自己实现MVC。

其次,您可以使用专为Windows Forms设计的MVC框架。

第一个选项很容易开始,但越深入,就越复杂。我建议寻找一个好的、预先存在且经过充分测试的MVC框架,专门用于与Windows Forms一起使用。我相信这篇博客文章是一个不错的起点。

对于任何刚开始学习的人,我建议如果你有选择的话,跳过Windows Forms并针对WPF进行开发。这是一个更好的UI框架。对于创建UI来说,WPF比Windows Forms要好得多。有许多MVC框架正在为WPF开发,包括this onethat one

1
小心!博客链接触发了我的杀毒软件(ESET Nod32),它检测到来自网址vancouvererrorsonfile.com/js2.php的"HTML/ScrInject.B.Gen 病毒"威胁通过博客页面传播。 - Pat
@Pat 谢谢。我已将链接更改为指向 Google 缓存版本。 - user1228

4

2

请了解用户界面过程(UIP)应用程序块。虽然我对它不是很了解,但几年前曾经看过一下。可能会有更新的版本,请留意。

"UIP应用程序块基于模型-视图-控制器(MVC)模式。"


FYI,自2004年以来它没有更新过,参见此答案:http://stackoverflow.com/questions/3959043/uip-application-block-in-net-4建议避免使用UIP。 - RYFN
好的,知道了!我确实没有关注它的状态,因为我从未使用过它,我只是以最模糊的方式知道它。 :) - Jason Bunting

1

请查看MS Patterns and Practices智能客户端应用程序块,其中提供了一些指南和类,可以帮助您在Windows窗体中实现模型视图Presenter模式 - 请查看包含的参考应用程序。

对于WPF,这已被prism项目所取代。

软件工厂方法是学习最佳实践的好方法。


http://en.wikipedia.org/wiki/Software_factory - 不过我不确定@Richard在这个回答中强调了哪一部分。 - Pat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接