Blue Theme Orange Theme Green Theme Red Theme
 
Team Foundation Server Hosting
Home | Forums | Videos | Advertise | Certifications | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
6 Months Free & No Setup Fees ASP.NET Hosting!
Search :       Advanced Search »
Home » WPF » MVVM implementation for Windows forms

MVVM implementation for Windows forms

In this article we will see how to implement the MVVM for the case of the Windows Forms.

Author Rank :
Page Views : 8939
Downloads : 268
Rating :
 Rate it
Level : Beginner
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
MVVMImplementation.zip
 
 
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 



I. Introduction

In a previous article I demonstrated how to implement an MVVM Model View View-Model patterns in case of WPF, Of Corse, there are a lot of articles, tutorials and books which talk about this, but the extraordinary thing is in fact that one can implement this pattern with other platforms, I mean Windows Forms, ASP.NET or so.

Let's remember that the MVVM pattern is largely adopted by professionals who essentially develop Silverlight and WPF Windows Presentation Foundation applications. The main purpose behind the adoption of this pattern is the application maintenance and the unit testing as the business logic is entirely located within a separate unity from the view which is in this case the user interface that is, the user interface code behind remains cleans with 0 line of code.

But the question for whom already applied the MVVM with the Avalon (Silverlight or/and WPF) how to implement such pattern in Windows forms case? Bechir has an answer for that; all required is to follow this cook recipe.

II.1 First step

Let's create a Windows form project, and design the just created Form1 as follow:

1.gif 

Figure 1

The controls are defined as follow, tree labels are added to the scene, the first one will have as text First operand, and the second will have as a text Second operand, the third one will serve as result displayer, therefore, we will leave its text property empty, it could be found just at the right of the button as the figure 1 displays. Then we add two text boxes and a button. Recall that we won't name any of those controls at all. We just add them to the scene and dispose them as mentioned in the figure 1 above. As you can guess, this interface will serve to leverage some arithmetic operations let's say an addition operation.

II.2 Second step

The second step consists on developing the view model

2.gif

As we can see here, the View model class contains a private field _form1 which is used to get the controls and do all the business at the View Model class. This class also contains a constructor.

public
ViewModel(Form1 form1)
{
    _form1 = form1;
    /*The loop is leveraged to search the button among controls
    And once it is found, the click event of that related button
    * will be raised */
    foreach (Control item in _form1.Controls)
    {
        if (item is Button)
       
            (item as Button).Click+=new EventHandler(ViewModel_Click);
        }
    }
    //This will lunch the form1 instance
    Application.Run(_form1);
}

As we can observe, a Form1 instance could be injected through the constructor, this one will play the role of the binder between the View Model and the user interface. Then a loop will be leveraged to search a button within the interface. Once the button is found then the click event will be registered. At the other hand, once the button is clicked the following event handler will be invoked:

protected
void ViewModel_Click(object sender, EventArgs args)
{
    int result = 0;
    int cumul;
    foreach (Control item in _form1.Controls)
    {
        if (item is TextBox)
       
            if(int.TryParse((item as TextBox).Text,out cumul))
            {
                result += cumul;
            }
        }
    }
    foreach (Control item in _form1.Controls)
    {
        /* As we remark here, we use the TabIndex property
        * to precise which label will be used to dislpay the
        result as we have three labels in the scene */
        if (item is Label && item.TabIndex ==5)
        {
            (item as Label).Text = result.ToString();
        }
    }
}

The main purpose of that event handler is to search for text boxes, then retrieve all texts' values and convert them to numeric values, the cumul variable will be used to add each text box text converted value to the result variable, once all text boxes are enumerated through that loop. Another loop will search for the label on which the result will be displayed, but the problem will be how to distinguish that label form the others as we have three labels in the scene, the solution is to use the TabIndex property to indicate which label to use for this purpose.

foreach
(Control item in _form1.Controls)
{
    /* As we remark here, we use the TabIndex property
    * to precise which label will be used to dislpay the
    result as we have three labels in the scene */
    if (item is Label && item.TabIndex ==5)
    {
        (item as Label).Text = result.ToString();
    }
}

This is now the complete code of the View Model class

///
<summary>
/// This is the view model class
/// </summary>
public class ViewModel
{
    //The form1 instance will be set once the view model is instanciated
    Form1 _form1;
    /// <summary>
    /// Cosntructor
    /// </summary>
    /// <param name="form1">This form1 will be injected in the view model</param>
    public ViewModel(Form1 form1)
    {
        _form1 = form1;
        /*The loop is leveraged to search the button among controls
        And once it is found, the click event of that related button
        * will be raised */
        foreach (Control item in _form1.Controls)
        {
            if (item is Button)
           
                (item as Button).Click+=new EventHandler(ViewModel_Click);
            }
        }
        //This will lunch the form1 instance
        Application.Run(_form1);
    }
    /// <summary>
    /// This event handler will be triggered when the button is
    /// clicked, the addtion operation will be leveraged and then
    /// the result will be displayed in the targeted label
    /// </summary>
    protected void ViewModel_Click(object sender, EventArgs args)
    {
        int result = 0;
        int cumul;
        foreach (Control item in _form1.Controls)
        {
            if (item is TextBox)
           
                if(int.TryParse((item as TextBox).Text,out cumul))
                {
                    result += cumul;
                }
            }
        }
        foreach (Control item in _form1.Controls)
        {
            /* As we remark here, we use the TabIndex property
            * to precise which label will be used to dislpay the
            result as we have three labels in the scene */
            if (item is Label && item.TabIndex ==5)
            {
                (item as Label).Text = result.ToString();
            }
        }
    }
}

II.3 Third step

The third step is a little bit optional but it could be very helpful, in cases those are more complex than our case. In this step we will use some reflection to indicate whether the View Model is activated, if yes, then the business logic is coupled with user interface. For this purpose we have developed a class attribute which is ViewModelAttribute and which has one unique Boolean property and we call it Activated property that will be used as  flag to indicate if the View Model is activated or not.

3.gif
 
This is an implementation of such class:

using
System;
namespace MVVMImplementation.Attribute
{
    [global::System.AttributeUsage(AttributeTargets.Class, 
                            Inherited = false, AllowMultiple = false)]
    sealed class ViewModelAttribute : System.Attribute 
    {
        public ViewModelAttribute() { }
        public ViewModelAttribute(bool Activated)
        {
            this.Activated = Activated;
        }
        public bool Activated { get; set; }
    }   
}

II.4 Fourth step

The final step consists of changing the way that the application uses to start:

We open the Progam.cs class and we change the code so that it appears like this:

using
System;
using System.Reflection;
using System.Windows.Forms;
using MVVMImplementation.Attribute;
namespace MVVMImplementation
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Initialize();
        }
        private static void Initialize()
        {
            Type t = typeof(Form1);
            object[] attributes = t.GetCustomAttributes(typeof(ViewModelAttribute), false);
            if (attributes.Length > 0 && (attributes[0] as ViewModelAttribute).Activated == true)
            {
                 Form1 form1 = new Form1();
                 ViewModel viewModel = new ViewModel(form1);
            }
            else
            {
                 Application.Run(new Form1());
            }
       }
    }
}

In that above code we used reflection to get information whether the Lunched Form1 is decorated with our custom attribute or not, and then we check if the Activated property is set to true

[ViewModel(true)]
public partial class Form1 : Form

If yes, then the View Model will be coupled within the current lunched instance 

   
Form1 form1 = new Form1();
    ViewModel viewModel = new ViewModel(form1);

If no then the View Model won't be coupled with the view and nothing happens when someone clicks on the result button.

II.5 Fifth step

Let's test the project and see what really happens, first let's decorate our Form1 as follow

using
System;
using System.Windows.Forms;
using MVVMImplementation.Attribute;
namespace MVVMImplementation
{
    [ViewModel(true)]
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

Now, we lunch the application and add some numbers to the both text boxes and click the result button

4.gif

In the other hand, let's change the value of the View Model constructor to false

using System;
using System.Windows.Forms;
using MVVMImplementation.Attribute;
namespace MVVMImplementation
{
    [ViewModel(false)]
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

5.gif

Nothing will happen in this case, because the View Model is not activated.

Now, let's try another tricky thing, first we turn back the value of that View Model to true then we add a third operand to the scene and we run the application, the surprise is that the application runs as normally, and the addition is done regardless on the recent user interface modification. Recall that we don't modified a single line of the View Model in one hand and we don't added any business logic to the view code behind.

6.gif
 
Conclusion: 

The Model View View-Model could be applied for other platform other than the Avalon (WPF and Silverligth) platform, as we see through this article, the MVVM is implemented for the case of the Windows Forms. The next time, I will demonstrate how to implement this pattern with ASP.NET 3.5.

Good Dotneting !!!

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Bechir Bejaoui

The author holds a master degree in NTIC specialized  in software developement delivered by the high school of communication SUPCOM, he also holds a bachelor degree in finance delivered by  the  economic sciences and  management  university of Tunis "FSEGT".

He also holds:

MCPD enteprise solutions developement 3.5 certification and MCTS distibuted application developement 2.0

 He's a freelance developer since 2006. Actually woking on the WPF, .Net framewok 3.5, silverlight and the other .Net new features, in addition, he is painter and sculptor.

Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the Top 5 .NET Memory Management Fundamentals
To write the best .NET code, you need to know exactly how the .NET framework really manages memory. Ricky Leeks presents the Top 5 fundamental facts of .NET memory management. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Discover the top 5 tips for understanding .NET Interop
Become a Sponsor
 Comments
Nice by Zhijun On March 3, 2010
Good.  Mark it. and I will study.
Reply | Email | Modify 
Nice by Zhijun On March 3, 2010
Good.  Mark it. and I will study.
Reply | Email | Modify 
Good article Bechir by Mahesh On March 3, 2010
Very good work.
Reply | Email | Modify 
ViewModel in C++ with View in WPF. by Santhosh On May 31, 2010

I was looking at any implementation of using Managed C++ for ViewModel and WPF as View.
Do you have any exposure on the same or can you throw some light on it.

I am interested in using ICommand in Managed C++. Is it possible?

Reply | Email | Modify 
Re: ViewModel in C++ with View in WPF. by Bechir On May 31, 2010

you can write a C++/CLI source and then create an interface a sort of adapter with  C# that stands between the xaml and the code behind

Reply | Email | Modify 
Re: Re: ViewModel in C++ with View in WPF by Santhosh On May 31, 2010

Yes... I am trying to do the same. I am using DelegateCommand in VC++ (the language I am not comfortable with) and am not successfull in doing so. I was successfull in using a delegate withought any problem. Is there any problem using DelegateCommand with VC++ as of your knowledge  or if you have any samples of the same please guide me to the same.

Regards,

Santhosh

Reply | Email | Modify 
Where's the Model? by Daniel On August 13, 2010
I'm quite new to C#/WinForms etc, so I apologize if this question has an obvious answer.  I see the View part and the ViewModel part- where is the Model itself?  Thanks!
Reply | Email | Modify 
Re: Where's the Model? by Bechir On August 14, 2010
You have right the model is not token in the consideration in this simple case, but this technique could also be adopted as MVVM implementation since there is not implementation at the form code behind level
Reply | Email | Modify 
Very nice and simple to understand the MVVM pattern. Thank you by Muralidhar On November 30, 2010

Thanks

Reply | Email | Modify 
This looks very not scalable... by Ilya On December 27, 2010
Your ViewModel is too dependent on the View. What if you had not just five controls in your form, but tens of controls with different functionalities? Would you still loop over them and access them by TabIndex? Besides, making your code dependent on tab index is a really bad idea, what if you want to reorder the controls or add another one in the middle?
Reply | Email | Modify 
Discover the top 5 tips for understanding .NET Interop
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.