Click here to Skip to main content
13,049,814 members (74,382 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


169 bookmarked
Posted 13 Apr 2012

MVVM (Model-View-ViewModel) Pattern For Windows Form Applications, using C#

, 9 May 2013
Rate this:
Please Sign up or sign in to vote.
It's a pattern like MVVM but for WinForms.


The MVVM pattern is in favour of WPF/Silverlight developers because of its advantages. Microsoft says that MVVM:

  • Separates the business and presentation logic of the application from its UI, and makes it much easier to test, maintain, and evolve.
  • Allows developers and UI designers to more easily collaborate when developing their respective parts of the application.(Look at the link)

MVVM is for WPF, but is there any way to have the advantages for WinForms too? The answer is yes (good news or maybe not so new). Windows Form Applications can also have the advantages, and of course it doesn't mean the exact real Model-View-ViewModel (MVVM) pattern. I searched and found many approaches (Google Search) some of them were great and some not(!) But I've tried to present a simple useful solution. I hope you'll be interested.


As you know, Program Logic and Content are separated In ASP.Net. And also in WPF, Program Logic is separated from UI. In Windows Forms, I preferred to use partial classes to separate Program Logic from UI until MVVM pattern has been introduced to me. I interested in using the pattern for WPF, so I decided to find a same way for WinForms too, but I was always too busy to work on it. One day, I tried to impose MVVM on WinForms, and here is the result of 3 spare hours working on the subject.

A very fast and short MVVM review

MVVM means Model-View-ViewModel:


1. View: It refers to the elements that displayed by the UI. As some people say, View is UI and some others say that View is UI "but" Logic (I like the second one). And also, it passes commands to ViewModel.

2. ViewModel: It's an abstraction of the View, or mediation between View and Model. It passes Data between View and Model.

3. Model: It represents data from DAL (Data Access Layer) or a Domain Model. So, Model is not DAL but refers to it.

Using the code

View: I need two forms (MainForm and ViewForm). MainForm contains a TextBox (NameForAdding) and a Button (Add). ListForm contains only one DataGridView.

OK, there is not any code behind of MainForm:

public partial class MainForm : Form

As you know, I used a partial class in a separated assembly (MainForm.CodeBehind.cs) for it:

public partial class MainForm
        private ViewModel viewModel;

        public MainForm()

        //Defining all Control handler methods       
        private void InitialControlHandlers()
            this.viewModel = new ViewModel();        
            ListForm listForm = new ListForm()
                ViewModel = this.viewModel
            //Defines the listForm as an owned form

            //Defines: if ListForm closes, the MainForm will close too
            listForm.FormClosing+=new FormClosingEventHandler(
                (object sender, FormClosingEventArgs e) =>

            //If the end user press Enter key, it will be like (s)he clicked on Add button. 
            this.NameForAdding.KeyPress += new KeyPressEventHandler(
                (object sender, KeyPressEventArgs e) =>
                    if (e.KeyChar == (char)13)

            this.Add.Click += new EventHandler(
                (object sender, EventArgs e) =>

            //Defining a command for this button. It will be un-boxed to execute.
            this.Add.Tag = viewModel.AddToListCommand;

            //Defining a command for TextChanged. It will be un-boxed to execute.
            this.NameForAdding.Tag = viewModel.TextChangedCommand;

            //Binding the Text property of ViewModel to TextBox
            BindingSource binding = new BindingSource();            
            binding.DataSource = viewModel.Text;
            this.NameForAdding.DataBindings.Add(new Binding("Text", viewModel, "Text"));

            //Showing ListForm at finishing  the form load.
        private void AddToList()
	    viewModel.Execute(this.Add.Tag, null);

            //After passing the value of the TextBox, it will be empty.
            this.NameForAdding.Text = string.Empty;


All events, methods and etc of the Form, are defined in the partial class.


public class ViewModel : INotifyPropertyChanged
        public string Text { get; set; }

        private ICommand _addToListCommand;
        public ICommand AddToListCommand
                if (_addToListCommand == null)
                    _addToListCommand = new AddToList(this);
                return _addToListCommand;

        private ICommand _textChangedCommand;
        public ICommand TextChangedCommand
                if (_textChangedCommand == null)
                    _textChangedCommand = new TextChanged(this);
                return _textChangedCommand;

        private ObservableCollection<StringValue> _nameList;
        public ObservableCollection<StringValue> NameList
                return _nameList;

                _nameList = value;
                _nameList.CollectionChanged += 
                        new System.Collections.Specialized.NotifyCollectionChangedEventHandler

        //PropeetyChanged Handlers
        void model_PropertyChanged(object sender, PropertyChangedEventArgs e)
            this.NameList = 
                               //For Geting any new Changes in Entity 

        void MyProperty_CollectionChanged
               (object sender, 
                      System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

        public void NotifyPropertyChanged(string propertyName)
            if (this.PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        //INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;        

        public void Execute(object sender, object parameter)

        //For more information about the complete code, download the Source Code 

And its constructor: 

public ViewModel()
      Model model = new Model();
      model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged);

And 2 command classes that are used in UI and ViewModel:

public class AddToList : ICommand
    public AddToList(ViewModel viewModel)
        this.ViewModel = viewModel;

    public ViewModel ViewModel { get; set; }

    //ICommand Members
    public void Execute(object sender)
        if (string.IsNullOrEmpty(this.ViewModel.Text))
        if (string.IsNullOrEmpty(this.ViewModel.Text.Trim()))
        this.ViewModel.NameList.Add(new StringValue(this.ViewModel.Text));

public class TextChanged : ICommand
    public TextChanged(ViewModel viewModel)
        this.DataAccess = viewModel;

    public ViewModel DataAccess { get; set; }

    //ICommand Members
    public void Execute(object sender)
        this.DataAccess.Text = sender.ToString();


public class Model:INotifyPropertyChanged
   public ObservableCollection<StringValue> List = new ObservableCollection<StringValue>();

   private DataAccess dal = new DataAccess();

   public Model()
      this.List = dal.Select();

      dal.DatabaseUpdated += new DataAccess.UpdateHandler(UpdataFromDal);

      this.List.CollectionChanged += 
                      new System.Collections.Specialized.NotifyCollectionChangedEventHandler

   void List_CollectionChanged(object sender, 
                            System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

   private void UpdataFromDal(ObservableCollection<StringValue> list)
      this.List = list;

      List.CollectionChanged += 
                      new System.Collections.Specialized.NotifyCollectionChangedEventHandler

      if (PropertyChanged != null)
         PropertyChanged(List, null);

   #region INotifyPropertyChanged Members

      public event PropertyChangedEventHandler PropertyChanged;


OK, and what about ListForm? ListForm has a DataGridView and a Property as ViewModel
I bound DataGridView to ViewModel.NameList:

private void BindDataGridView()
   BindingSource binding = new BindingSource();
   binding.DataSource = ViewModel.NameList;
   this.DataGridView.DataSource = binding;

void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)

And in form Load event:

ViewModel.PropertyChanged += new PropertyChangedEventHandler(ViewModel_PropertyChanged);

Illustrating generalities

If I want to use the "Inverted Pyramid" illlustrating:

  • In the example, The end user is able to enter a name in the main form (MainForm) for many times, and seeing the names that are adding to the GirdView of the other form (ListForm)
  • The end user is also confronting with some new names in ListForm that (s)he has never added them, like when another users are updating the list (just a simulating)
  • Adding proccess in the "end user"'s observation is 1.Filling the TextBox. 2. Click on Add (Button) 3. Watching the result in ListForm.
  • In behind, When the TextBox (NameForAdding) changes, Text property of ViewModel will change (because of binding) and when the Button (Add) is clicked, a command will fire to add Text to List of Model. After it, Model will synchronize it's List with database (using DataAccess). If it will be any changes in List, then NameList of ViewModel will update and any updates in NameList, re-bind the GridView in ListForm.
  • 2-Ways Binding is not available in WinForm, so I've implemented INotifyPropertyChanged and used NotifyCollectionChangedEventHandler.

Sequence Diagram

Answering Obscurities

What is StringValue? A string object has only one public Property (Length) and if you bind a string collection to the DataGridView, it will only show the lengths. StringValue is a defined class and I created a Collection of StringValue to be shown in the DataGirdView.

public class StringValue
   public string Value { get; set; }
   public StringValue(string value)
      this.Value = value;

What is ICommand? It's an interface that I created, imitating WPF build-in ICommand Interface:

public interface ICommand
   void Execute(object sender);

I set the Tag of the controls to commands (In partial class)

this.Add.Tag = viewModel.AddToListCommand;
this.NameForAdding.Tag = viewModel.TextChangedCommand;

The tags will be un-boxed when it's going to execute its command:

public void Execute(object sender, object parameter)

Why didn't I expound enough about ViewModel class? Because, it's almost like View-Model in WPF and there are enough sites, books, articles and etc to refer. (A too long article because of untimelies).

Why does Model seem a little strange? Model uses DataAcess class simulating it's working with a database (but it isn't). All about Model is, it's a gate between Presentation and DAL, in the meanwhile, it has implemented INotifyPropertyChanged to notify ViewModel about entity updates.

What does DataAccess do? DataAccess class is not a part of the pattern, I created it to fake an accessing to database. It's also generating some random names to simulate concurrency updates. (Please download demo and source code.)

Anything else?
Please help! If you face any ambiguity in this writing, please notify me, and don't hesitate to ask question. It helps me to improve the article.

Thank you.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Shahin Khorshidnia
Software Developer (Senior)
Iran (Islamic Republic of) Iran (Islamic Republic of)
Microsoft Certified Technology Specialist (MCTS)

"شاهین خورشیدنیا"

Nobody is perfect and neither am I, but I am trying to be more professional. In my humble opinion, you have to develop your skills, as long as you are responsible for developing even a tiny part of a sustainable software. That makes this job so special to me.

You may also be interested in...


Comments and Discussions

QuestionBest implementation of mvvm for winform!! Pin
Rahman Mahmoodi16-Mar-16 20:20
memberRahman Mahmoodi16-Mar-16 20:20 
GeneralGood Stuff! Pin
Member 109339929-Jul-14 20:20
memberMember 109339929-Jul-14 20:20 
SuggestionMVVM Pattern & suggested improvements Pin
Fredrik Claesson28-Aug-13 21:53
memberFredrik Claesson28-Aug-13 21:53 
GeneralAlready tried.... With better bindings and events... There are limitations in winforms that prevent a serious implementation Pin
Jorge Varas13-May-13 9:24
memberJorge Varas13-May-13 9:24 
GeneralRe: Already tried.... With better bindings and events... There are limitations in winforms that prevent a serious implementation Pin
Shahin Khorshidnia13-May-13 18:14
memberShahin Khorshidnia13-May-13 18:14 
GeneralMy vote of 2 Pin
AndyVGa10-May-13 17:27
memberAndyVGa10-May-13 17:27 
SuggestionBad project name and bad rely of dlls. Pin
leiyang-ge8-May-13 22:54
memberleiyang-ge8-May-13 22:54 
GeneralThank you very much Pin
Shahin Khorshidnia9-May-13 1:54
memberShahin Khorshidnia9-May-13 1:54 
GeneralMy vote of 5 Pin
ehsan.vc2-Jan-13 0:46
memberehsan.vc2-Jan-13 0:46 
GeneralRe: My vote of 5 Pin
Shahin Khorshidnia2-Jan-13 7:12
memberShahin Khorshidnia2-Jan-13 7:12 
GeneralMy vote of 5 Pin
B.Farivar16-Sep-12 1:37
memberB.Farivar16-Sep-12 1:37 
GeneralRe: My vote of 5 Pin
Shahin Khorshidnia16-Sep-12 1:59
memberShahin Khorshidnia16-Sep-12 1:59 
QuestionMVVM FX Pin
Tiago Freitas Leal13-Jun-12 12:21
memberTiago Freitas Leal13-Jun-12 12:21 
AnswerRe: MVVM FX Pin
Shahin Khorshidnia13-Jun-12 18:36
memberShahin Khorshidnia13-Jun-12 18:36 
GeneralRe: MVVM FX Pin
Tiago Freitas Leal13-Jun-12 20:38
memberTiago Freitas Leal13-Jun-12 20:38 
GeneralRe: MVVM FX Pin
Brisingr Aerowing10-Mar-14 14:56
professionalBrisingr Aerowing10-Mar-14 14:56 
Questionprimary goal Pin
tomas oplt15-May-12 4:38
membertomas oplt15-May-12 4:38 
The question is:

What is primary goal of this solution?
Is it better than classic WinForm solution ?
Is it faster ?
Is it more readable?
Is it simpler ?
Is it better to underestand ?
Is it less error prone ?

Why should I use this approach in Windows Forms ?

AnswerRe: primary goal Pin
Shahin Khorshidnia15-May-12 6:21
memberShahin Khorshidnia15-May-12 6:21 
GeneralMy vote of 5 Pin
Monjurul Habib10-May-12 19:29
memberMonjurul Habib10-May-12 19:29 
GeneralRe: My vote of 5 Pin
Shahin Khorshidnia7-Aug-12 8:26
memberShahin Khorshidnia7-Aug-12 8:26 
Generalmy vote of 5 Pin
Uday P.Singh5-May-12 0:54
memberUday P.Singh5-May-12 0:54 
GeneralRe: my vote of 5 Pin
Shahin Khorshidnia5-May-12 1:21
memberShahin Khorshidnia5-May-12 1:21 
GeneralMy vote of 5 Pin
AUDIBMW27-Apr-12 21:55
memberAUDIBMW27-Apr-12 21:55 
GeneralRe: My vote of 5 Pin
Shahin Khorshidnia29-Apr-12 3:46
memberShahin Khorshidnia29-Apr-12 3:46 
GeneralMy Vote of 5 Pin
BITA Moin26-Apr-12 6:01
memberBITA Moin26-Apr-12 6:01 
GeneralRe: My Vote of 5 Pin
Shahin Khorshidnia26-Apr-12 6:22
memberShahin Khorshidnia26-Apr-12 6:22 
GeneralRe: My Vote of 5 Pin
BITA Moin26-Apr-12 9:21
memberBITA Moin26-Apr-12 9:21 
GeneralRe: My Vote of 5 Pin
Shahin Khorshidnia27-Apr-12 6:47
memberShahin Khorshidnia27-Apr-12 6:47 
GeneralMVVM in Winform is not recomemded Pin
Ankush Bansal25-Apr-12 0:47
memberAnkush Bansal25-Apr-12 0:47 
GeneralThank you Pin
Shahin Khorshidnia25-Apr-12 1:46
memberShahin Khorshidnia25-Apr-12 1:46 
GeneralRe: Thank you Pin
Ankush Bansal25-Apr-12 2:41
memberAnkush Bansal25-Apr-12 2:41 
GeneralRe: Thank you Pin
Shahin Khorshidnia25-Apr-12 6:14
memberShahin Khorshidnia25-Apr-12 6:14 
GeneralRe: Thank you Pin
Ankush Bansal25-Apr-12 20:10
memberAnkush Bansal25-Apr-12 20:10 
GeneralRe: Thank you Pin
Shahin Khorshidnia26-Apr-12 1:42
memberShahin Khorshidnia26-Apr-12 1:42 
QuestionRe: MVVM in Winform is not recomemded Pin
Jorge Varas7-Aug-12 4:08
memberJorge Varas7-Aug-12 4:08 
AnswerRe: MVVM in Winform is not recomemded Pin
Shahin Khorshidnia7-Aug-12 7:14
memberShahin Khorshidnia7-Aug-12 7:14 
QuestionCheck out Winforms.MVVM Pin
Jorge Varas16-Apr-12 9:04
memberJorge Varas16-Apr-12 9:04 
AnswerThank you Pin
Shahin Khorshidnia16-Apr-12 12:37
memberShahin Khorshidnia16-Apr-12 12:37 
QuestionRegarding MVVM Pattern For Windows Form Applications, using C# Pin
Tridip Bhattacharjee15-Apr-12 20:14
memberTridip Bhattacharjee15-Apr-12 20:14 
AnswerRe: Regarding MVVM Pattern For Windows Form Applications, using C# Pin
Shahin Khorshidnia16-Apr-12 1:04
memberShahin Khorshidnia16-Apr-12 1:04 
QuestionMy Vote of 5 Pin
Adam Morocco14-Apr-12 4:16
memberAdam Morocco14-Apr-12 4:16 
AnswerRe: My Vote of 5 Pin
Shahin Khorshidnia14-Apr-12 4:24
memberShahin Khorshidnia14-Apr-12 4:24 
QuestionNice starter Pin
GanesanSenthilvel14-Apr-12 3:15
memberGanesanSenthilvel14-Apr-12 3:15 
AnswerThank you Pin
Shahin Khorshidnia14-Apr-12 3:17
memberShahin Khorshidnia14-Apr-12 3:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170713.1 | Last Updated 9 May 2013
Article Copyright 2012 by Shahin Khorshidnia
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid