Windows Forms的UI设计模式(类似于WPF中的MVVM)

171

MVVM最常用于WPF,因为它非常适合。但是对于Windows Forms呢?是否有一种既被广泛采用的方法/设计模式也能很好地与Windows Forms配合使用? 是否有书籍或文章能够描述得很好呢?也许基于MVP或MVC的方法可行吗?


请参考 https://dev59.com/BnRB5IYBdhLWcg3wV196#682216 中有关在Windows窗体中实现MVC的内容。 - Ian Ringrose
6
这似乎是一个好问题。看看投票和星级评价。 - nawfal
18
为什么这不是有建设性的,明明这正是我在寻找的对话?适度管理,而非指挥! - CAD bloke
基本上,WinForms的MVVM是可行的。但大多数人更愿意谈论他们过去如何使用MVP/MVC,而不是推动Winforms/MVVM的想法。或者他们更喜欢纠结于它实际上被称为Presenter Model而不是MVVM,以及MVVM对于WPF有多么好。 - H. Abraham Chavez
12
当这种类型的问题被关闭为“不具建设性”时,我总是感到失望,因为正如另一位发帖者已经提到的那样,这种讨论正是我来这里寻找的。版主们,请采取更开明的态度,放松“不具建设性”的标准。 - Tim Long
10个回答

98
我尝试过MVP模式,它似乎在Windows窗体下也很好用。 这本书提供了一个使用MVP模式的Windows窗体示例(样本薪资应用程序)。该应用程序并不复杂,但可以让您了解如何创建它。 《C#敏捷原则、模式与实践》……
您可以在源代码中获取源代码。

编辑:

有两种MVP模式(a)被动视图和(b)监督控制器

对于复杂的数据绑定场景,我更喜欢使用监督控制器模式。在监督控制器模式中,数据绑定任务由视图负责。因此,对于TreeView/DataGrid,这应该在相应的视图中完成,只有与视图无关的逻辑才应该移至Presenter。

我建议查看以下MVP框架:MVC# - MVP框架

不要被名字所迷惑(它是一个MVP框架)。

简单的WinForms MVP视频:WinForms-MVP

处理下拉列表的示例:MVP-DropDownList

简单的TreeView绑定示例(穷人版绑定)。您可以在BindTree()中添加任何树状视图特定的逻辑。

以下是代码片段...尚未经过测试,直接从思路键入....

public interface IYourView
{
   void BindTree(Model model);
}

public class YourView : System.Windows.Forms, IYourView
{
   private Presenter presenter;

   public YourView()
   {
      presenter = new YourPresenter(this);
   }

   public override OnLoad()
   {
         presenter.OnLoad();
   }

   public void BindTree(Model model)
   {
       // Binding logic goes here....
   }
}

public class YourPresenter
{
   private IYourView view;

   public YourPresenter(IYourView view)
   { 
       this.view = view;
   }

   public void OnLoad()
   {
       // Get data from service.... or whatever soruce
       Model model = service.GetData(...);
       view.BindTree(model);
   }
}

1
谢谢,那本书中的例子对我来说有些太简单了。如果我想在Winforms和MVP中展示更复杂的数据,例如TreeView或DataGridView,应该如何处理逻辑?哪些部分需要包含多少逻辑? - bitbonk
我已经更新了答案并将检查是否可以获得更多信息。 - rajesh pillai
1
BindTree方法对我来说似乎有点不完善。突然间,视图了解了模型。这是一件好事吗?肯定有很多人面临这些问题。我很惊讶居然没有关于它的书籍。因为在.NET世界中几乎什么都有相关的书籍。 - bitbonk
1
那不是一个缺陷。这是MVP模式的“Supervisory Controller”风格。在Supervisor Controller中,视图知道模型(这是一种展示模型)。另一种是“被动视图”,其中视图完全与模型解耦。 - rajesh pillai
这个链接视频要求我安装Flash Player... - JonathanPeel

14
正如所说,我在使用Winforms时一直使用MVP模式。但是你使用的设计模式并不意味着你会正确使用。有许多反模式与MVP相关联。
如果您想以良好的方式开始所有工作,您必须使用构建智能客户端的框架。因此,我建议使用以下设计和实践:Smart Client Software Factory http://www.codeplex.com/smartclient 您可以在这里讨论当前的智能客户端框架:http://codebetter.com/blogs/glenn.block/archive/2008/05/10/prism-cab-and-winforms-futures.aspx PS:我喜欢这篇有关MVP反模式的文章:http://blog.mattwynne.net/2007/06/13/mvp-smells/ 希望这有所帮助。

此外,我们做了一个WinForm MVP应用程序,认为这将是很棒的。最终,我们意识到这是一种不好的方法,并转向了MVC。从理论上看,它看起来很棒,但遇到了很多问题,变得难以承受。 - Nick Turner

9
Model-View-ViewModel (MVVM)模式是一种设计模式。按照定义,设计模式展示了面向对象世界中的常见解决方案,并且这个解决方案可以应用于不同的平台(如WPF、WinForms、Java Swing等)。我认为MVVM最好与WPF一起使用,因为它利用了强大的绑定能力。然而,Windows Forms也支持数据绑定。 WAF Windows Forms Adapter演示了如何在Windows Forms应用程序中应用MVVM模式。

3
WAF 是为 WPF 而设计的,不是为 Windows Forms 设计的。链接具有误导性。 - Bentley Davis
3
链接并不误导。WAF Windows Forms Adapter附带一个MVVM应用程序,它实现了两次:1. WinForms;2. WPF。这两个应用程序共享与UI技术无关的较低层。 - jbe

5
我写过一种MVP/MVVM设计模式的变体,称为MVP-VM,它是Winforms应用程序的定制解决方案,需要全面测试覆盖,并使用数据绑定作为保持演示与模型数据同步的主要机制。 .NET Winforms的MVVM MVVM(Model View View Model)引入了类似的方法,用于在赋予数据绑定能力的环境(WPF)中将演示与数据分离。由于.NET Framework 2.0已经提供了先进的数据绑定基础架构,还允许应用程序对象在设计时进行绑定 - 因此,“视图模型”实体可以很好地适合基于MVP的环境。

5
我曾向两位技术同事提出了同样的问题:MVVM是否适用于WindowsForms?他们都给出了完全相同的答案:“不可能!WindowsForms缺少WPF和Silverlight的丰富绑定(OneTime,OneWay,TwoWay,OnewayToSource),也缺少TypeConverters。
  • 屏幕激活器模式适用于WindowsForms——您可以在此处找到它:这里,由jagui从Caliburn.Micro移植而来
  • 丰富的绑定和TypeConverters——Kent Boogaart的Truss以一种与UI无关的方式实现
  • 命令——WPF应用程序框架(WAF)有一个WafWinFormsAdapter项目,可以处理一些MVVM事项,即命令

再次强调,我们能否在WinForms中使用MVVM? 是的,我们拥有所有的组件。我们只需要把它们粘合在一起就可以了。


4
你可以使用企业架构、模式和实践作为起点,尽管它们有些过时。
在一般指导下,有.NET应用程序架构:设计应用程序和服务,这是.NET方式和分层N层应用程序的良好介绍。 alt文本http://i.msdn.microsoft.com/ms954595.f00aa01%28en-us%2CMSDN.10%29.gif

如果想了解更多正式的“模式”,可以参考使用Microsoft .NET的企业解决方案模式alt text
(来源:microsoft.com)

以下是一些例子:


4

我认为MVP模式非常适合WinForms开发,这在Microsoft的WinForms框架CAB中得到了部分证明。

我在WinForms中使用MVP来提取代码,因为无法测试View代码。此外,还可以使需要重用(或重复)的代码保持不在View中,因此无法共享。

我可以参考我自己的项目,其中我使用了MVP模式ExceptionReporter.NET。虽然我确定我没有完美地使用它。

你提到MVVM适用于WPF - 我认为原因是因为WPF有很强的数据绑定支持。如果你在WPF中没有使用数据绑定(当然并不是强制性的),那么可以选择MVP。重点是,MVP对于任何客户端应用程序都是一个强有力的选择。即使在WPF中,如果您计划在不是WPF的项目之间共享代码,MVP可能是一个“更好”的选择。

了解在WinForms中使用MVP的价值,可观看Boodhoo关于使用MVP的视频演示: http://www.bestechvideos.com/2008/06/29/dnrtv-show-14-jean-paul-boodhoo-on-model-view-presenter 以及该作者撰写的MSDN文章: http://msdn.microsoft.com/en-us/magazine/cc188690.aspx


Boodhoo的东西似乎是关于WebForms而不是WinForms。除非视频后面还有更多的内容...? - Roger Lipscombe

3
BindTree方法对我来说似乎有些缺陷。突然间视图了解模型,这是一件好事吗?肯定有很多人面临这种问题。我惊讶的是没有任何关于此类问题的书籍。因为在.NET世界中,几乎关于所有东西都有书籍。
这些设计并不是关于隐藏模型,而是精确定义应用程序不同层之间的交互。您可以完全更改后端,只要通过Bindtree传递一个模型,您的用户界面将继续工作。
现在,在Rajesh给出的示例中,Model类可能是一个不好的名称选择。它可以是TreeData或RecordsData。无论如何定义,它都具有使用Winforms绑定机制将特定控件绑定到底层数据所需的内容。
浏览这种材料的最佳网站是这里。Martin Fowler收集了各种有用的UI设计模式和企业设计模式。
再次强调,关键在于使用接口精确定义每个层如何相互交互。
在我的应用程序(用于运行金属切割机的CAD / CAM应用程序)中,我的结构看起来像这样。
- 实施表单界面 - UIDLL与视图实现视图接口,通过表单接口与表单交互。特定视图在UIViewDLL中注册,视图执行在命令库中找到的Command Objects,这些对象与模型交互。 - 命令库;实现ICommand的命令列表。与视图交互的命令通过UIViewDLL中公开的接口进行交互。 - UIViewDLL;公开命令使用的View Interfaces。 - Model;构成我的应用程序核心数据结构的类和集合。对我来说,这些是诸如材料、切割路径、形状、片材、火炬等东西。 - 实用程序;一个DLL,具有我公司常用的跨不同应用程序的实用程序类。例如复杂的数学函数。

2

我读过的第一个好的UI设计模式解释是Jeremy Miller的博客 - Building Your Own CAB。它描述了常见的模式 - 被动视图(Passive View)、MVP等,并介绍了在C#中实现它们的一些方法。


1
您可以尝试使用MugenMvvmToolkit,它允许在WinForms中使用“纯MVVM”。 由于它支持所有平台上的绑定,因此所有原生绑定功能都可用于WPF平台,并且在所有平台上都可用(包括WinForms)。

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