How would you implement MVC in a Windows Forms application?
Solution 1:
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.
Solution 2:
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.
Solution 3:
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.
Solution 4:
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.
Solution 5:
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."