使用 Windows 窗体实现 MVC
Posted
技术标签:
【中文标题】使用 Windows 窗体实现 MVC【英文标题】:Implementing MVC with Windows Forms 【发布时间】:2010-10-13 20:58:10 【问题描述】:我在哪里可以找到一个关于如何在 Windows 窗体中完全实现 MVC 模式的好例子?
我在各种站点(例如,The Code Project 和 .NetHeaven)上找到了许多教程和代码示例,但其中很多比 MVC 更能代表观察者模式。由于我要开发的应用程序是针对学校项目的,因此我不太愿意使用PureMVC 或MVC# 之类的框架。
【问题讨论】:
How would you implement MVC in a WindowsForms application?的可能重复 另见How to make Databinding type safe and support refactoring 【参考方案1】:我认为应用程序之间是如此不同,我们对如何编写应用程序的理解仍然非常有限。我过去使用过的 Windows 窗体应用程序彼此如此不同。我看到的一些设计差异是(包括大多数组合):
直接与数据库对话(2 层) 使用为给定应用程序编写的后端(3 层) 使用一组 Web 服务,这些服务是为许多应用程序使用而编写的,并且不能针对您的应用程序进行更改。 (面向服务的架构) CRUD 操作正在完成更新 正在使用command pattern 完成更新(向后端服务器发送命令) 大量使用data binding / 没有使用数据绑定 大多数数据是“类似表格”(例如发票),在标准网格控件中运行良好/大多数 UI 数据需要自定义控件。 一个开发人员/由 10 或 20 个开发人员组成的团队(仅在 UI 上) 大量使用模拟等的单元测试/没有单元测试因此,我认为不可能创建一种始终适合的 MVC(或 MVP)实现。
我见过的真正解释 MVC 和为什么 MVC 系统是这样构建的最好的帖子是"Build Your Own CAB" series by Jeremy D Miller。在工作之后,您应该能够更好地理解您的选择。 Microsoft's Smart Client Guidance (CAB / Microsoft Composite Application Block) 也应该考虑。它有点复杂,但它可以很好地适用于适合的应用程序。
选择MVC/MVP Implementation for a Winforms Project 给出一个值得一读的概述。很多人喜欢PureMVC。没用过,下次需要MVC框架的时候再看看。
“Presenter First”是一种软件开发方法,它结合了 Model View Presenter (MVP) 设计模式和test-driven development 的思想。它使您可以从用客户的语言编写测试开始。例如:
“当我点击‘保存’按钮时 该文件应该被保存并且 未保存的文件警告应该 消失。”
我没有使用“Presenter First”的经验,但有机会我会尝试一下,因为它看起来很有前途。
您可能希望查看的其他 Stack 溢出问题是 here 和 here。
如果您想在任何时候使用 WPF,请查看Model-View ViewModel (MVVM) 模式。这是一个非常好的视频,您应该看看:Jason Dolinger on Model-View-ViewModel。
MVVM (Model View View Model) Design Pattern for Winforms 提供另一个选项,如果需要,可以更轻松地转换为 WPF。 Magical.Trevor 是另一个适用于 Windows 窗体的 MVVM 示例,它还包括基于属性名称的自动绑定。
同时问问自己为什么你在使用 MVC。
您希望能够对尽可能多的代码进行单元测试吗? 您是否试图让尽可能多的代码被重用? 您是否想让您的代码库易于理解? 对给定项目有效的 101 个其他原因。一旦您明确了自己的目标,就可以更轻松地选择一种或另一种实现方式。
【讨论】:
@AgnelKurian,CAB 是 Microsoft 提供的关于如何构建应用程序的一组示例代码 - 现在大部分已成为历史。 哈哈!是的,我现在记得那些“应用程序块”。【参考方案2】:更新:除了我之前的回答,我建议阅读"Presenter First" approach(尤其是 PDF 文章)
我会推荐 MVP(实际上是 PassiveView 模式)而不是 MVC。您实际上并不需要任何特殊的框架,这只是您组织代码的方式。
一种方法(我通常采用的)是将每个窗口窗体拆分为三个实体:
-
演示者/控制器类 - 这是您在开发表单时实际开始的内容。这是您的大部分/所有“业务”逻辑应该驻留的地方。
一个视图接口(IView),它包含方法、属性和事件。此界面是演示者了解您的表单的所有。
最后,当你完成了presenter和view的实现(包括单元测试),你就可以创建实际的表单类,并让它实现IView接口。然后就是向表单添加适当的控件并将它们连接到界面的问题。
示例代码(一个简单的伪代码,仅用于说明):
interface IView
string Username get; set;
string Password get; set;
event EventHandler LogOnButtonClicked;
void InformUserLogOnFailed();
void MoveToMainScreen();
class Presenter
public Presenter(IView view)
this.view = view;
view.LogOnButtonClicked += new EventHandler(OnLogOnButton);
private void OnLogOnButton()
// we ask some service to verify the username/password
bool isLogOnOk = logOnService.IsUserAndPasswordOk(view.Username, view.Password);
if (isLogOnOk)
view.MoveToMainScreen();
else
view.Username = "";
view.Password = "";
view.InformUserLogOnFailed();
private IView view;
class Form : IView
public Form()
presenter = new Presenter(this);
public string Username
get return TextBoxUsername.Text;
set TextBoxUsername.Text = value;
public string Password
get return TextBoxPassword.Text;
set TextBoxPassword.Text = value;
public void InformUserLogOnFailed()
MessageBox.Show("Invalid username or password.");
public void MoveToMainScreen()
// code for opening another form...
private Presenter presenter;
【讨论】:
这是一个名为 PassiveView 的 MVP 变体的实现。在被动视图中,视图不应该选择他的演示者。对于类似的示例(但视图非常被动),请查看此示例 danieleteti.it/?p=221(Delphi 语言示例)【参考方案3】:你看过PureMVC吗?我发现,一旦他们开始构建特定的实现,没有人能就 MVC 的真正样子达成一致。
更新:您可以从MobileMVC 等更简单的东西开始构建自己的。 Compact Framework 代码应该可以在 Windows 上编译/运行。由于这是一项学校作业,我建议您实际上花一些时间了解 MVC 的实际工作原理。
【讨论】:
我有一个非常简单的应用程序来管理书店的学校作业,我非常不愿意使用像 PureMVC 这样的框架。我正在寻找更简单的东西。【参考方案4】:您可能想看看Differential Execution。
这里是SourceForge
IMO,这是对 MVC 的巨大改进,尽管它仍然很不寻常。
【讨论】:
【参考方案5】:可以在here 中找到使用 Windows 窗体滚动您自己的 MVC 实现的一个很好的示例。包含源代码。
当您阅读、研究和编写此作业的代码时,您会发现对于如何实现 MVC 存在很多分歧。这是一个简单的案例,它反映了关注点的分离,也是一个很好的例子,说明了将其连接起来所需的“管道”。
当您离开学校时,您可能希望像其他海报所推荐的那样使用框架。
【讨论】:
【参考方案6】:Microsoft 复合接口应用程序块作为 MVC 实现开始它的生命(在它实现的其他模式中)。然而,发布版本演变为 MVP 实现,可以说是对 MVC 概念的一种不同解释。
如果您愿意检查一个非常完整(并且有些复杂)的 MVP 实现的代码,您可以发现 MS-CAB 作为 Microsoft 智能客户端软件工厂的组件之一。它带有源代码。你可以找到它here。祝你好运!
【讨论】:
以上是关于使用 Windows 窗体实现 MVC的主要内容,如果未能解决你的问题,请参考以下文章