Introduction

Model-view-controller (MVC) is a pattern used to isolate business logic from the user interface. Using MVC, the Model represents the information (the data) of the application and the business rules used to manipulate the data, the View corresponds to elements of the user interface such as text, checkbox items, and so forth, and the Controller manages details involving the communication between the model and view. The controller handles user actions such as keystrokes and mouse movements and pipes them into the model or view as required.

Background

Using the Code

Note: I strongly recommend you download the code to view it, it will be much easier.

Here I will show an example of our good old friend calculator in a MVC architecture. A brief overview; the Form will house the view and events will be passed to the controller who will then call methods on our model such as ADD/Subtract/NumberPress. The model takes care of all the work and it holds the current state of the calculator. The tough thing about MVC is where to slice it apart can be confusing. The end goal is a pluggable UI and perhaps multiple controllers attached to the same model. So one way to test if you did it right is to quickly write another UI and plug it in.

A typical MVC patterns instantiation looks something like the following. A few important things to notice; the controller takes an interface to the view and model. It is important to know that the view will typically interact with the controller if it needs notification of events which are fired via the view (such as a button click). In this case, I have the controllers constructor pass a reference to itself to the view class.

Notice that the view does not interact with the model, it simply receives update requests from the controller. The controller will access the view through the Total property. The view also passes click events on to the controller.

This View shouldn't know about the Controller, except we need to give it notification of some events so we pass in a IController. We will invoke event handlers on the controller via IController.

Other Information

MVC is often seen in web applications, where the view is the actual HTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML. Finally, the model is represented by the actual content, usually stored in a database or XML files, and the business rules that transform that content based on user actions.

Though MVC comes in different flavors, control flow generally works as follows:

The user interacts with the user interface in some way (e.g. presses a button).

A controller handles the input event from the user interface, often via a registered handler or callback.

The controller notifies the model of the user action, possibly resulting in a change in the model's state. (e.g. controller updates user's shopping cart).

A view uses the model (indirectly) to generate an appropriate user interface (e.g. the view produces a screen listing the shopping cart contents). The view gets its own data from the model. The model has no direct knowledge of the view.

The user interface waits for further user interactions, which begins the cycle anew.

By decoupling models and views, MVC helps to reduce the complexity in architectural design, and to increase flexibility and reuse.

Pushing the "Instance" of the form to the controller (as a parameter to the method: public CalcController( ICalcModel model, ICalcView view) is opposite of what I think the real MVC pattern is theoretically trying to accomplish. This tightly makes the "Controller" have to deal with the "frmCalc" type

If you keep the 'view' in the view, in this case a windows form, and then the controller can
operate independently of what views it is serving.

I would suggest a different approach:

Controller Instantiates a new object called Calc which implements ICalcModel, then
passes that as an "ICalcModel" instead of a "Calc" type.

The "View" or form code, now Calls Controller, expecting an ICalcModel type returned like this:

Windows Form Code-Behind:
Calc calc = (Calc)Controller.GetCalc()

so now whatever UI comes along, you can just
add a new method to the controller that sends a different "ICalcModel" type back to the view. In this case, I may add a class to the Controller called "CalcMobileDevice", which implements the "ICalcModel" interface, and send that back to the new mobile device "view"

Now, my new mobile device form receives back the same "type" as my old windows form, but
the guts on the inside of the implementation is slimmed down for the smaller screen size.

Hi everybody, I followed all your code and made my own class but I get an error at compilation momment: "Access incompatibility"
Please can you tell me what is wrong in my code? I would much appreciate it.
Aldo Abril
(Error 1 Incoherencia de accesibilidad: el tipo de parámetro 'TresCapas.IControlador' es menos accesible que el método 'TresCapas.frmVista.agregaListener(TresCapas.IControlador)' D:\Proyectos\Libres\TresCapas\TresCapas\Form1.cs 24 21 TresCapas)

A few things make me an impression. The first thing is that the controller takes an interface to the view. I think when the controller takes an interface to the view, then we talk no more for Model-View-Controller, but it is matter of Model-View-Presenter.
Second: i see that the controller is responsible for transferring the data from the view to the model. That's OK, but also it is responsible for the reverse data moving (from the model to the view). That is another sign of the MVP.

I would like to suggest a little improvement:
First you could move the Total property from the view to the model (and of course you should change its return value from string to int or double). Second, force your model to implement the INotifyPropertyChanged interface. And third use data binding to bind the result display to the Total property of the model. Thus you will be unconcern about the transfer of the result from the model to view and it will saves you few lines of code.

What is your opinion?
Except those remarks, I think the article is pretty good.

If you have time, maybe you could send me your improvements and I will update the article. I'm super busy at the moment and to be honest I don't fully understand the implications of your comments without seeing the code.

Actually what i wanted was the app to work the same as a calculator that act only when another operation comes and not on every click of the number. I am able to enter > 1 digit number only the first time and not after that -

What i want is to hide the operation logic from the controller. The example passes number ans sets state. Why dont yu pass both at the same time. I used your example and modified it as below:
(only problem now is text get appended, but results are ok after second click to an operation)

...how you 're getting such high ratings when the formatting in your article sucks so bad.

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

When I posted the code, the formatting seems to get messed up, I had to even put the tabs in again by hand. If you want to fix it for me and tell me whats wrong, I would much appreciate it. Perhaps I should just remove the code snippets because they don't really help and seem to the source of my formatting problems. Or is it something else?

Quick rant on complaints:
I love how people complain about article formatting. It's sort of like if you borrow your neighbors lawn mower and complain the color is faded and send it back. When I go to code project I look for code, I think a lot of people should be on formattingProject.com where writers also get paid money.