I don't develop too many desktop / Windows Forms applications, but it had occurred to me that there may be some benefit to using the MVC (Model View Controller) pattern for Windows Forms .NET development.
Has anyone implemented MVC in Windows Forms? If so, do you have any tips on the design?
What I've done in the past is use something similar, Model-View-Presenter.
[NOTE: This article used to be available on the web. To see it now, you'll need to download the CHM, and then view the file properties and click Unblock. Then you can open the CHM and find the article. Thanks a million, Microsoft! sigh]
The form is the view, and I have an IView interface for it. All the processing happens in the presenter, which is just a class. The form creates a new presenter, and passes itself as the presenter's IView. This way for testing you can pass in a fake IView instead, and then send commands to it from the presenter and detect the results.
If I were to use a full-fledged Model-View-Controller, I guess I'd do it this way:
The form is the view. It sends commands to the model, raises events which the controller can subscribe to, and subscribes to events from the model.
The controller is a class that subscribes to the view's events and sends commands to the view and to the model.
The model raises events that the view subscribes to.
This would fit with the classic MVC diagram. The biggest disadvantage is that with events, it can be hard to tell who's subscribing to what. The MVP pattern uses methods instead of events (at least the way I've implemented it). When the form/view raises an event (e.g. someButton.Click), the form simply calls a method on the presenter to run the logic for it. The view and model don't have any direct connection at all; they both have to go through the presenter.
Well, actually Windows Forms implements a "free-style" version of MVC, much like some movies implement some crappy "free-style" interpretation of some classic books (Romeo & Juliet come to mind).
I'm not saying Windows Forms' implementation is bad, it's just... different.
If you use Windows Forms and proper OOP techniques, and maybe an ORM like EntitySpaces for your database access, then you could say that:
The ORM/OOP infrastructure is the Model
The Forms are the Views
The event handlers are the Controller
Although having both View and Controller represented by the same object make separating code from representation way more difficult (there's no easy way to plug-in a "GTK+ view" in a class derived from Microsoft.Windows.Forms.Form).
What you can do, if you are careful enough. Is keep your form code completely separate from your controller/model code by only writing GUI related stuff in the event handlers, and all other business logic in a separate class. In that case, if you ever wanted to use GTK+ to write another View layer, you would only need to rewrite the GUI code.
Windows Forms isn't designed from the ground up to use MVC. You have two options.
First, you can roll your own implementation of MVC.
Second, you can use an MVC framework designed for Windows Forms.
The first is simple to start doing, but the further in you get, the more complex it is. I'd suggest looking for a good, preexisting and well-tested, MVC framework designed to work with Windows Forms. I believe this blog post is a decent starting point.
For anybody starting out, I'd suggest skipping Windows Forms and developing against WPF, if you have the option. It's a much better framework for creating the UI. There are many MVC frameworks being developed for WPF, including this one and that one.
According to Microsoft, the UIP Application Block mentioned by #jasonbunting is "archived." Instead, look at the Smart Client Application Block or the even newer Smart Client Software Factory, which supports both WinForms and WPF SmartParts.
Check into the User Interface Process (UIP) Application Block. I don't know much about it but looked at it a few years ago. There may be newer versions, check around.
"The UIP Application Block is based on the model-view-controller (MVC) pattern."
Take a look at the MS Patterns and Practices Smart Client application block which has some guidance and classes which walk you through implementing a model view presenter patter in windows forms - take a look at the reference application included.
For WPF this is being superseced by the prism project
The software factories approach is a great way to learn best practices
Related
I have a WPF GUI application based on MVVM design and data binding. Now, I want to reuse the core code (i.e. the data model) in a Windows service, or a console UI app, or a WinForms app.
Is such a design reasonable? If yes, what are the pitfalls?
Or should I make a standalone data model instead, and interface WPF via wrappers?
UPDATE:
Sorry, I should have been more precise. Let me clarify: I don't doubt the very modularity thing =) My concern boils down to having my current DataModel implement INotifyPropertyChanged, use DispatcherTimers, etc. -- all that non-GUI but still WPF stuff. The model's business logic is based on it.
Is this (non-GUI WPF) design acceptable for reuse in the aforementioned cases, or should I abstract further, until no references to WPF would be required at all?
Yes, this is perfectly acceptable and most of the time it is desired!
When you build an MVVM app, it should be in at least 3 formal layers:
Presentation WPF, UI, xaml, behaviors. All that stuff. Not reusable
Application The view models and structure that supports your application rules. All that stuff. Not intended for reuse
Foundation Database access, business objects. Domain specific algorithms. Ideally this bit should be reusable anywhere
The foundation layer is the clever bit. This is where the meat in your application sandwich is. It makes perfect sense for this to be totally agnostic of UI technology. WPF, winforms, ASP. It shouldn't even need a UI.
Edit for question update:
Removing all references to WPF is hard because sometimes you need a CollectionViewSource on your view models for grouping/filtering of results. That is a WPF class.
It is very tempting to view your seperation-of-concerns as 'just dont reference wpf' and that helps but it can make life difficult. Instead, try to be disciplined with the type of behaviors you are putting in. If you find yourself writing 'clever' (domain) code on a view model, shift it to the foundation layer as a business object method or extension. Similarly, if you find yourself implementing IValueConverter often, perhaps you should make better use of view models.
One thing is for sure, your foundation layer should never, ever, ever reference WPF.
Such a design is very reasonable! You can create a portable C# library for all .NET technologies including WPF, WinRT, ASP MVC, etc which can contain your models. Obviously you'll need to wrap these portable models into a viewmodel anyway, but IPropertyChanged is implemented in all XAML flavors.
I like the concept of REST wherein each page is stateless. However, I haven't seen anyone using it in windows application. Way back, when I'm still using MVC and MVP patterns, one of my setbacks is handling states.
I don't know if this is a good idea, but I like to know your opinion on this. :)
Thanks.
I guess it depends on how you implement this. My view models typically keep state in properties that the views can bind to. However, I have sometimes found it useful to keep that state information in a separate object, which my view model hangs on to. My view can still bind to it and it declutters my view model.
I've built two large winforms apps using REST and I'm starting to experiment with WPF. WPF should be even easier.
I use MVC on the server for my REST resources and MVC on the desktop.
All of the WinForms wizards I've written in the past have a high degree of coupling between the UI and the model. That is: the individual pages know about enabling/disabling the Next/Previous buttons, how to react to the Next button being pressed, etc. It makes it all hard to test, because to test any of the logic, you've got to put a lot of scaffolding together first.
I've been using MVC (in the form of ASP.MVC) recently, and I'm finding that easy to test. I've also had a play with WPF, and I think I'm getting my head around M-V-VM.
I'm struggling with the M-V-P pattern in WinForms (i.e. no WPF-style databinding). In particular, I need to implement a wizard.
Would I have a controller per page? A view model that governs the whole wizard? Something else?
This is in WinForms (not WPF), in C#. .Net 2.0 preferred.
In the end I opted for something between MVVM and MVP, using a mixture of WinForms databinding and view callback interfaces. I guess it's closer to MVP than MVVM. Each page has a viewmodel/presenter, and the wizard itself has its own viewmodel/presenter to govern flow (certain options skip later wizard pages, for example).
It turned out pretty well, and it fairly easy to write unit tests for each of the presenter classes.
The underlying wizard framework doesn't use MVVM or MVP. It's just plain ol' WinForms code.
Have a look at the Smart Client Software Factory.
MVVM is most commonly used with WPF because it is perfectly suited for it. But what about Windows Forms? Is there an established and commonly used approach / design pattern like this for Windows Forms too? One that works explicitly well with Windows Forms? Is there a book or an article that describes this well? Maybe MVP or MVC based?
I have tried MVP and it seems to work great with windows forms too.
This book has an example of windows forms with MVP pattern (sample payroll application). The application is not that complex but will give you an idea about how to go about creating it.
Agile Principles, Patterns, and Practices in C#...
You can get the source code at
Source Code
EDIT:
There are two variations of the MVP pattern
(a) Passive view and (b) supervising controller
For complex databinding scenarios I prefer to go with the Supervising controller pattern.
In supervising controller pattern the databinding responsibility rest with the view. So,for treeview/datagrid this should be in the respective views, only view agnostic logic should moved on to the presenter.
I'll recommend having a look at the following MVP framework
MVC# - An MVP framework
Don't go by the name (it's an MVP framework).
Simple winforms MVP video
Winforms - MVP
An example of dealing with dropdown list
MVP - DropDownList
Simple treeview binding example (poor man's binding). You can add any treeview specific logic in BindTree().
Below is the code snippet.... not tested, directly keyed in from thought....
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);
}
}
As it has already said, i always worked in a MVP pattern when using Winforms. But the design pattern you will use not mean you will use right. There is loads of anti-pattern attached to MVP.
If you want to starts everything in a good manner, you have to use the framework for building smart client. So i will recommend to use that design and practices: Smart Client Software Factory http://www.codeplex.com/smartclient
You have a discussion here about the current smart client frameworks : http://codebetter.com/blogs/glenn.block/archive/2008/05/10/prism-cab-and-winforms-futures.aspx
PS: I like this post on the MVP anti-patterns: http://blog.mattwynne.net/2007/06/13/mvp-smells/
Hope this helps
The Model-View-ViewModel (MVVM) Pattern is a design pattern. Per definition a design pattern shows a common solution in the object-oriented world and this solution can be applied in various platforms (WPF, WinForms, Java Swing, etc.). I agree that MVVM is best used with WPF because it leverages the strong binding capabilities. However, Windows Forms supports data binding as well.
The WAF Windows Forms Adapter shows how to apply the MVVM Pattern in a Windows Forms application.
I have written about a variation of MVP/MVVM design patterns called MVP-VM, which is a tailor made solution for winforms applications that require full testing coverage and use data binding as main mechanism for keeping the presentation updated with model data.
MVVM for .NET Winforms
MVVM (Model View View Model)
introduces similar approach for
separating the presentation from the
data in an environment that empowers
data binding (WPF). Since .NET
framework 2.0 already offers advanced
data binding infrastructure that also
allows design time binding of
application objects - the ‘View Model’
entity can fit quite well in MVP based
environment.
I asked this same question to two of my techies co-workers: is MVVM for WindowsForms possible? Both gave me the exact same answer: "No way! WindowsForms is missing the rich bindings of WPF and Silverlight (OneTime, OneWay, TwoWay, OnewayToSource) and it is also missing the TypeConverters."
Screen Activator Pattern for WindowsForms - you can find it here, ported from Caliburn.Micro by jagui
Rich Bindings and TypeConverters - Truss by Kent Boogaart, does it in an UI independent way
Commands - WPF Application Framework (WAF) has a WafWinFormsAdapter project that takes care of some MVVM stuff namely commands
Again, can we have MVVM for WinForms?
Yes we can. We have all the pieces. We just have to glue them together.
I believe that MVP is a pattern well-suited to WinForms development - as is partly evidenced by it's use in CAB - Microsoft's framework for WinForms.
I use MVP in WinForms to extract code out of the View - because I can't test the View code. And also to enable code that needs to be reused (or is duplicated) to stay out of the View where it can't be shared.
I can refer to my own project where I use the MVP pattern ExceptionReporter.NET. Though I'm sure I don't use it perfectly.
You mentioned MVVM working for WPF - I think the reason for that is because of strong data-binding support. If you were not using data-binding in WPF (and it's certainly not compulsory) then you could choose MVP. The point being that MVP is a strong choice for any client-side application. And possibly a 'better' choice, even in WPF, if you plan on sharing code between projects that aren't WPF.
For more evidence of the value of using MVP in WinForms see Boodhoo's video presentation on using MVP:
http://www.bestechvideos.com/2008/06/29/dnrtv-show-14-jean-paul-boodhoo-on-model-view-presenter
And an MSDN article by the same author at http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
The BindTree method seems a little
flawed to me. Suddenly the the View
knows abou the Model. Is that a good
thing? There must be tons of poeple
being confronted with these kind of
problems. I am surprised that there
aren't any books about it. Since there
are books about everything in the .NET
world.
These Design not about hiding the model rather precisely defining the interactions between the different layers of the applications. You can change the backend completely and as long as you pass a Model through Bindtree your UI will continue to work.
Now class Model may be a poor choice of a name in the example that Rajesh gives. It can be TreeData, or RecordsData. However you define it, it has what you need to using the binding mechanism of Winforms to bind a specific control to the underlying data.
The best site to browse for this kind of material is here. Martin Fowler has collected a variety of useful UI design pattern and enterprise design patterns.
Again the key to this is the use of interfaces to precisely define how each layer interact with each other.
In my own application (a CAD/CAM applications used to run metal cutting machines) my structure looks like this.
Forms implementing form interfaces
UIDLL with views implementing view
interfaces that interact with forms
through the form interface. The
specific views register themselves
with UIViewDLL Views executes Command Objects found
in command libraries that interact
with the Model.
Command libraries; lists of
commands implementing ICommand.
The command that interact with
views do so through the interfaces
exposed in UIViewDLL.
UIViewDLL; exposes the View Interfaces
used by the commands.
Model; the classes and collection that
make up core data structures of my
application. For me these are things
like material, cuttingpaths, shape,
sheets, torches, etc.
Utility; a DLL that has commonly used
utility classes used by my company
that span different application. For
example complex math functions.
You can use Enterprise Architecture, Patterns and Practices as the starting point, although they are slightly dated.
Under General Guidance there is Application Architecture for .NET: Designing Applications and Services, which is a good introduction to .NET ways and layered N-tier application.
alt text http://i.msdn.microsoft.com/ms954595.f00aa01%28en-us%2CMSDN.10%29.gif
For more formal "patterns", there is Enterprise Solution Patterns Using Microsoft .NET.
(source: microsoft.com)
To name a few,
Model-View-Controller
Intercepting Filter
Three-Layered Services Application
The first good explanation of UI design patterns I read was in Jeremy Miller's blog - Building Your Own CAB. It describes the common patterns - Passive View, MVP, etc. and addresses some of the ways you might implement them in C#.
You can try MugenMvvmToolkit that allows to use a "pure MVVM" for WinForms.
Due to the fact that it supports bindings on all platforms, all of the native binding features available for WPF platform available on all platforms (include WinForms).
I am a bit confused in what the application controller should do? Because I see the functionality will also exists in your MVP pattern to make the decisions which form should be shown when a button is clicked? Are there any good examples for Windows Forms that uses the application controller pattern?
There is a difference in the MVC(ontroler) and the Application Controller. I know the MVC(ontroller), I am not sure what is the responsibilities for an Application Controller, and how does it fit into a WinForms application. Martin Fowler also calls this the Application Controller pattern, surely it is not the same thing as the MVC(ontroller)?
I recently wrote an article on creating and using an ApplicationController in a C# Winforms project, to decouple the workflow and presenters from the forms directly. It may help:
Decoupling Workflow And Forms With An Application Controller
edit:
Archive.org has got a more readable copy of the article at this time.
An Application Controller is a bit of a different beast than the controller used in MVC.
Martin Fowler's page on the Application Controller.
In the case of an MVP WinForms app, which seems to be what the question topic is about I think. You can put all the logic for "what form do I show now" into the Presenter, but as your application grows you're going to be duplicating a lot of code between Presenters.
Say you have 2 views that both have a button for "Edit this Widget", both of them would have to have logic to get a WidgetEditorPresenter and show the associated view. If you have an ApplicationController, you move that logic into the ApplicationController, and now you simply have a dependency in all your presenters on the ApplicationController and you can call appController.EditWidget() and it will pop up the correct view.
The application controller is an uber-controller that controls application flow throughout your system as you move from screen to screen.
Personally I have no experience with MVP or winforms, but I have worked with MVC. I hope this is what you're asking, otherwise ignore my answer completely.
The C in MVC is responsible for more than just choosing the next view to be presented to the client. It holds most, preferably all, business-logic of the application, including performance of system tasks (such as logging and enforcement of permissions upon the flow of data from the model and to it).
Its primary task is, naturally, to serve the presentation layer above it and separate it from the model layer below while mediating between them. I guess you can think of it as the brain of the application.
Hope this helps,
Yuval =8-)