One of the biggest hurdles I find WinForms developers struggling with when learning WPF and the MVVM design pattern, is understanding the shift in thought process that is used for WPF/MVVM development.
Here’s the best way I can summarize the difference:
- In WinForms, your forms and UI objects are your application.
- In WPF/MVVM, the class objects you build are your application, while UI objects are nothing more than a user-friendly interface for interacting with your application objects.
For example, suppose we were asked to make a simple Registration form that takes down a user’s Name, Email Address, and asks them if they want to receive Special Offers or not.
A WinForms developer’s thought process might be to think “I need a Window that contains a TextBox for name, TextBox for email, CheckBox for if they want special offers or not, and a Button to submit the form. When the Submit button is pressed, the data is taken from the UI objects, and saved to the database.”
In contrast, a WPF developer’s thought process is “I need a Window that contains a RegistrationForm object. This class needs a string for the Name, a string for the EmailAddress, a boolean property for if they want special offers or not, and a Command to submit the data.”
But of course WPF doesn’t know how to draw a class of type RegistrationForm, so we’ll have to tell it how to draw the RegistrationForm object using a Template. This template would probably render the Name and EmailAddress properties using TextBoxes, the IsSpecialOffers property with a CheckBox, and provide a Button to run the SaveDataCommand, although that doesn’t have to be the case and is something that can be figured out later.
With WPF, the UI layer and the application layer are so completely separated that you don’t actually need the UI layer at all. If you wanted, you could run your application entirely by test scripts, or through a console window. The actual application layer never needs to reference any UI object to get its data.
Using this concept on a larger scale
In fact, this thought process is used on a much broader scale for the entire WPF/MVVM application.
Want a LoginWindow to come up, and on successful login switch to the MainWindow? No problem, simply start the program with your LoginClass, and on successful Login return the ApplicationClass.
Want to have an application with separate Windows for Products, Orders, and Customers? No problem, create your ApplicationClass to hold a List<T> of available “Window” objects containing the classes representing each “Window”, and include a SelectedWindow property which identifies which window object is currently active.
Of course, WPF needs to know how to draw these class objects, so you’ll need to tell it to use a specific DataTemplate, UserControl, Page, or maybe even Window when rendering these objects.
This is not meant to be an in-depth look at how WPF is different from WinForms or how to switch from WinForms to WPF, but is more of a brief summary on the change in mindset needed when moving from WinForms to WPF.
With WPF, your application consists of the objects you create, and you use DataTemplates and UI objects to tell WPF how to draw your application components. That’s the opposite of WinForms where you build your application out of UI objects, and then supply them with the data needed.
Once you grasp this key difference, WPF becomes much easier to understand and work with.