Add your own alternative version
Stats
706.7K views 18.2K downloads 72 bookmarked
Posted
8 Apr 2008
|
Comments and Discussions
|
|
how can i modify this code so i can add multiple digit numbers ex: 22+333 ?
|
|
|
|
|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MVCExample
{
/// <summary>
/// All interaction with the calculator's view should go through here.
/// This View doesn't know about the Controller, except that it could provide methods for registering a Controller's listeners or delegates.
/// </summary>
interface ICalcView
{
void AddListener(IController controller);
string Total
{
get;
set;
}
};
/// <summary>
/// Windows Form that will host our MVC based functionality.
///
/// </summary>
public partial class frmCalcView : Form, ICalcView
{
IController controller;
public frmCalcView()
{
InitializeComponent();
}
/// <summary>
/// The view needs to interact with the controller to pass the click events
/// This could be done with delegates instead.
/// </summary>
/// <param name="controller"></param>
public void AddListener(IController controller)
{
this.controller = controller;
}
private void lbl_Click(object sender, EventArgs e)
{
// Get the text out of the label to determine the letter and pass the click info the controller to distribute.
controller.OnClick((Int32.Parse(((Label)sender).Text)));
}
private void lblPlus_Click(object sender, EventArgs e)
{
controller.OnAdd();
}
private void label9_Click(object sender, EventArgs e)
{
// controller.
controller.ONsubtract();
}
private void label11_Click(object sender, EventArgs e)
{
controller.OnMultiplication();
}
private void label12_Click(object sender, EventArgs e)
{
controller.OnClear();
}
private void label13_Click(object sender, EventArgs e)
{
controller.OnDivision();
}
#region ICalcView Members
public string Total
{
get
{
return textBox1.Text;
}
set
{
textBox1.Text = value;
}
}
#endregion
}
/// <summary>
///
/// </summary>
public interface IController
{
void OnClick(int number);
void OnAdd();
void ONsubtract();
void OnMultiplication();
void OnDivision();
void OnClear();
}
/// <summary>
/// The controller process the user requests.
/// Based on the user request, the Controller calls methods in the View and Model to accomplish the requested action.
/// </summary>
class CalcController : IController
{
ICalcModel model;
ICalcView view;
public CalcController(ICalcModel model, ICalcView view)
{
this.model = model;
this.view = view;
this.view.AddListener(this);
}
public void OnClick(int number)
{
view.Total = model.SetInput(number).ToString();
}
public void OnClear()
{
view.Total = "0";
model.ChangeToClear();
}
public void OnAdd()
{
model.ChangeToAddState();
}
public void ONsubtract()
{
model.ChangeTosubState();
}
public void OnMultiplication()
{
model.ChangeTomulState();
}
public void OnDivision()
{
model.ChangeTodivState();
}
}
/// <summary>
/// Calculator model, The model is independent of the user interface.
/// It doesn't know if it's being used from a text-based, graphical, or web interface
/// </summary>
interface ICalcModel
{
/// <summary>
/// This will process the number supplied and return a result based on it's internal state;
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
int SetInput(int number);
// int Clear();
/// <summary>
/// Adds two numbers
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <returns></returns>
int Add(int value1, int value2);
/// <summary>
/// Subtracts two numbers
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <returns></returns>
int Subtract(int value1, int value2);
int Multiplication(int value1, int value2);
int Division(int value1, int value2);
/// <summary>
/// Change State to Adding
/// </summary>
void ChangeToAddState();
//Change State to substract
void ChangeTosubState();
void ChangeTomulState();
void ChangeTodivState();
void ChangeToClear();
};
/// <summary>
/// Calculator model, The model is independent of the user interface.
/// It doesn't know if it's being used from a text-based, graphical, or web interface
/// This particular model holds the state of the application and the current value.
/// The current value is updated by SetInput
/// </summary>
class CalculatorModel : ICalcModel
{
public enum States { NoOperation, Add, Subtract, Multiplication, Division,Clear };
States state;
int currentValue;
public States State
{
set { state = value; }
}
public int SetInput(int number)
{
if (state == States.NoOperation)
{
currentValue = number;
}
else if (state == States.Add)
{
currentValue = Add(currentValue, number);
}
else if (state == States.Subtract)
{
currentValue = Subtract(currentValue, number);
}
else if (state == States.Multiplication)
{
currentValue = Multiplication(currentValue, number);
}
else if (state == States.Division)
{
currentValue = Division(currentValue, number);
}
else if (state == States .Clear )
{
currentValue = number;
}
return currentValue;
}
public void ChangeToAddState()
{
this.state = States.Add;
}
public void ChangeTosubState()
{
this.state = States.Subtract;
}
public void ChangeTomulState()
{
this.state = States.Multiplication;
}
public void ChangeTodivState()
{
this.state = States.Division;
}
public int Add(int value1, int value2)
{
return value1 + value2;
}
public int Subtract(int value1, int value2)
{
return value1 - value2;
}
public int Multiplication(int value1, int value2)
{
return (value1 * value2);
}
public int Division(int value1, int value2)
{
return (value1 / value2);
}
public void ChangeToClear()
{
this.state = States.Clear ;
}
}
}
|
|
|
|
|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MVCExample
{
/// <summary>
/// All interaction with the calculator's view should go through here.
/// This View doesn't know about the Controller, except that it could provide methods for registering a Controller's listeners or delegates.
/// </summary>
interface ICalcView
{
void AddListener( IController controller );
string Total
{
get;
set;
}
};
/// <summary>
/// Windows Form that will host our MVC based functionality.
///
/// </summary>
public partial class frmCalcView : Form, ICalcView
{
IController controller;
public frmCalcView( )
{
InitializeComponent();
}
/// <summary>
/// The view needs to interact with the controller to pass the click events
/// This could be done with delegates instead.
/// </summary>
/// <param name="controller"></param>
public void AddListener( IController controller )
{
this.controller = controller;
}
private void lbl_Click(object sender, EventArgs e)
{
// Get the text out of the label to determine the letter and pass the click info the controller to distribute.
controller.OnClick((Int32.Parse(((Label)sender).Text)));
}
private void lblPlus_Click(object sender, EventArgs e)
{
controller.OnAdd();
}
private void label9_Click(object sender, EventArgs e)
{
// controller.
controller.ONsubtract ();
}
#region ICalcView Members
public string Total
{
get
{
return textBox1.Text;
}
set
{
textBox1.Text = value;
}
}
#endregion
}
/// <summary>
///
/// </summary>
public interface IController
{
void OnClick(int number);
void OnAdd();
void ONsubtract();
}
/// <summary>
/// The controller process the user requests.
/// Based on the user request, the Controller calls methods in the View and Model to accomplish the requested action.
/// </summary>
class CalcController : IController
{
ICalcModel model;
ICalcView view;
public CalcController( ICalcModel model, ICalcView view)
{
this.model = model;
this.view = view;
this.view.AddListener(this);
}
public void OnClick( int number )
{
view.Total = model.SetInput(number).ToString();
}
public void OnAdd()
{
model.ChangeToAddState();
}
public void ONsubtract()
{
model.ChangeTosubState ();
}
}
/// <summary>
/// Calculator model, The model is independent of the user interface.
/// It doesn't know if it's being used from a text-based, graphical, or web interface
/// </summary>
interface ICalcModel
{
/// <summary>
/// This will process the number supplied and return a result based on it's internal state;
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
int SetInput(int number);
/// <summary>
/// Adds two numbers
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <returns></returns>
int Add(int value1, int value2);
/// <summary>
/// Subtracts two numbers
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <returns></returns>
int Subtract(int value1, int value2);
/// <summary>
/// Change State to Adding
/// </summary>
void ChangeToAddState();
//Change State to substract
void ChangeTosubState();
};
/// <summary>
/// Calculator model, The model is independent of the user interface.
/// It doesn't know if it's being used from a text-based, graphical, or web interface
/// This particular model holds the state of the application and the current value.
/// The current value is updated by SetInput
/// </summary>
class CalculatorModel : ICalcModel
{
public enum States { NoOperation, Add, Subtract };
States state;
int currentValue;
public States State
{
set { state = value; }
}
public int SetInput ( int number )
{
if (state == States.NoOperation)
{
currentValue = number;
}
else if (state == States.Add)
{
currentValue = Add(currentValue , number );
}
else if (state == States.Subtract)
{
currentValue = Subtract(currentValue, number);
}
return currentValue;
}
public void ChangeToAddState()
{
this.state = States.Add;
}
public void ChangeTosubState()
{
this.state = States.Subtract;
}
public int Add( int value1, int value2 )
{
return value1 + value2;
}
public int Subtract(int value1, int value2)
{
return value1 - value2;
// throw new System.ApplicationException(" Not implemented yet");
}
}
}
|
|
|
|
|
|
Because after constructor:
public CalcController( ICalcModel model, ICalcView view)
i realised who is the boss here
Thanks
|
|
|
|
|
|
MVC is an old architecture
there is a new and complete architecture that's very better than MVC
it's the newest and i suggest u to work with it.
it's fantastic
u can download it from :
http://SourceForge.net/projects/shine-enterpris/files/[^]
also a document is availabe for that
it's a complete pattern for every thing not just an architecture !!!
contact me !
|
|
|
|
|
Hi - Thanks for a good article.
Observer pattern is the "key" for MVC pattern to work. Are you using this.
Regards
|
|
|
|
|
MVC is an old architecture
there is a new and complete architecture that's very better than MVC
it's the newest and i suggest u to work with it.
it's fantastic
u can download it from :
http://SourceForge.net/projects/shine-enterpris/files/[^]
also a document is availabe for that
it's a complete pattern for every thing not just an architecture !!!
contact me !
|
|
|
|
|
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.
|
|
|
|
|
MVC is an old architecture
there is a new and complete architecture that's very better than MVC
it's the newest and i suggest u to work with it.
it's fantastic
u can download it from :
http://SourceForge.net/projects/shine-enterpris/files/[^]
also a document is availabe for that
it's a complete pattern for every thing not just an architecture !!!
contact me !
|
|
|
|
|
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)
public partial class frmVista : Form, IVista
{
IControlador controlador;
public frmVista() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e){
controlador.onClick();
}
public void agregaListener(IControlador controlador) {
this.controlador = controlador;
}
public string Total {
get {
return textBox1.Text;
}
set {
textBox1.Text = value;
}
}
}
interface IVista {
void agregaListener(IControlador controlador);
string Total{
get;
set;
}
};
interface IControlador {
void onClick();
}
class Controlador : IControlador {
IVista vista;
IModelo modelo;
public Controlador(IVista vista, IModelo modelo) {
this.vista = vista;
this.modelo = modelo;
vista.agregaListener(this);
}
public void onClick() {
vista.Total = modelo.getNombre();
}
}
interface IModelo {
string getNombre();
}
class Persona : IModelo {
string _nombre = "Aldo";
public string getNombre() {
return _nombre;
}
}
|
|
|
|
|
whats the exact error msg?
|
|
|
|
|
This is the exactly error :
Error 1 Inconsistent accessibility: parameter type 'TresCapas.IControlador' is less accessible than method 'TresCapas.frmVista.agregaListener(TresCapas.IControlador)' G:\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.
Cheers,
R.J.
|
|
|
|
|
I understood this project which simplifies the concept of MVC for me,thanks, BUT I tried to apply that in a web project and I have a problem:
frmCalcView view = new frmCalcView(); ---> how can I do this line in web?
CalculatorModel model = new CalculatorModel();
CalcController controller = new CalcController(model, view);
I can put these code lines in global.asax instead of program.cs BUT how can I pass the view which is my default.aspx to the controller?
Another question confusing me, Is not the code behined of each page the controller of that page and the aspx the view? if so then the concept of MVC in web is nonsense !!
|
|
|
|
|
I'm not sure what you mean but you could do something like
Session.add( "View1" new frmCalcView() );
The view and controller could be a singleton but that would defeat some of the purpose. Look up asp.net singletons to learn how to best use that.
|
|
|
|
|
Is it necessary for the controller to be aware of the operation?
cant it treat operation i.e '+', '-' the same way it treats numbers.
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 - 
|
|
|
|
|
I'm not sure I understand your question.
|
|
|
|
|
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)
change the form code as :
private void lbl_Click(object sender, EventArgs e)
{
textBox1.Text += Int32.Parse(((Label)sender).Text);
}
private void lblOperation_Click(object sender, EventArgs e)
{
controller.OnClick((Int32.Parse(textBox1.Text)), ((Label)sender).Text[0]);
}
public interface IController
{
void OnClick(int number, char op);
}
modify Controller as:
public void OnClick( int number , char op)
{
view.Total = model.SetInput(number, op).ToString();
}
interface ICalcModel
{
int SetInput(int number, char op);
}
modify CalculatorModel as :
int currentValue;
char? operation;
public int SetInput ( int number , char op)
{
if (operation.HasValue)
{
int value = OperationFactory.GetOperation(operation.Value).Calculate(currentValue, number);
currentValue = value;
operation = op;
}
else
{
currentValue = number;
operation = op;
}
return currentValue;
}
Add following lines of code in the form :
interface IOperation
{
int Calculate(int value1, int value2);
}
class NoOperation : IOperation
{
#region IOperation Members
public int Calculate(int value1, int value2)
{
return value1;
}
#endregion
}
class AddOperation : IOperation
{
#region IOperation Members
public int Calculate(int value1, int value2)
{
return value1 + value2;
}
#endregion
}
class SubstractOperation : IOperation
{
#region IOperation Members
public int Calculate(int value1, int value2)
{
return value1 - value2;
}
#endregion
}
class OperationFactory
{
public static IOperation GetOperation(char op)
{
IOperation oper;
switch (op)
{
case '+':
oper = new AddOperation();
break;
case '-':
oper = new SubstractOperation();
break;
default:
oper = new NoOperation();
break;
}
return oper;
}
}
modified on Monday, May 5, 2008 6:35 PM
|
|
|
|
|
...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
|
|
|
|
|
It was only because the article was so new that it had a high rating.
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.
|
|
|
|
|
|
General News Suggestion Question Bug Answer Joke Praise Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
|