|
|
|
|
|
Home
»
WPF
»
MVVM implementation for Windows forms
|
|
|
|
Author Rank :
|
|
|
Page Views :
|
8939
|
|
Downloads :
|
268
|
|
Rating :
|
Rate it
|
|
Level :
|
Beginner
|
|
|
|
|
Download
Files:
|
|
|
|
|
|
|
|
|
|
|
|
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:
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

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.
 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

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(); } } }

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.
 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
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
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.
|
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!
|
|
|
|
|
|
|
|
|
|
|
|
|