Cookie Notice

Wednesday, 30 January 2019

Updating WinForms with WPF/XAML… Adding MVVM

The intent of this blog entry is provide some guidance for WinForm developers wanting to migrate their apps to a more modern application architecture without throwing the existing app out and starting over completely.  I think that there is also some help here for XAML developers wondering how to make use of their spectacular UX design skills in updating an existing WinForm application (again without throwing out everything).

I hope to have an entry for each step in the process and you can feel free to jump in and out as you wish.  Once you have the basics, you might not care about adding MVVM but it’s here for you should you need it.

Updating WinForms with WPF/XAML
  1. Getting Started
  2. Adding MVVM
  3. Adding Commands
  4. Messaging between Technologies
  5. XAML Islands – Where we want to be!

3rd Party Libraries

Ok, so now we have our Hello World working, it’s time to start building out some of the smarts behind it.  We’ll take the simplest approach to this and use a great 3rd party library called MVVM Light toolkit.  This will quickly get us up and running with full separation of our UX and code.

We are starting from the conclusion of the last blog entry, the Basics.  You should already have a simple WinForms application with a WPF User control display the ubiquitous “Hello World” text.

So, to begin we are going to use NuGet to load the MVVM Light library.  You can get the MVVM Light libs either through the NuGet package manager or the package manager console.

To get it through the package manager follow these instructions:

Package Manager: Search for “MvvmLightLibs” from the “Browse” tab.  Install that library.  We install the libs only so we don’t get a bunch of the bits we don’t need in a WinForm.

OR

Console: PM> Install-Package MvvmLightLibs

The View Model

There are plenty of definitions of MVVM out there so I won’t bother you with those details.  Suffice it to say that we want a View that has our WPF/XAML control and we want a view model where we’ll handle all the code.  The last piece, the model we’ll squeeze in but it just contains the data definitions that we, hopefully, are connecting to our UX.

The view model will basically contain all the properties and methods that will be bound to our view.  For example, if we have two pieces of information we need entered, first and last name, we would have a first and last name property.  The catch is that we need to make sure those properties properly communicate with the View.  Fortunately MVVM Light gives all those methods pre-canned and ready to rock.  There is an interface under the covers called INotifyPropertyChanged that is monitored by bound controls in XAML.  In the included library we have that interface implement in a very simple way. 

Tutorial

  1. Right click on the ViewModels folder (created previously) and select Add/Class
  2. For consistency lets call the class “UserControl1VM”
  3. make the class “public”
  4. add “ViewModelBase” as the inherited class (it’s from MVVM Light and will give us all the bit we need to make use of INotifyPropertyChanged.
  5. I would also add a public constructor for this class called “public UserControl1VM()” so we have a place to initialize data or properties if we need to.
  6. public class UserControl1VM : ViewModelBase
    {
         public UserControl1VM()
         {
         }
    }
  7. Add one property to our VM. We’ll call it HelloVar.  We’ll do it as a full variable which will give us more control over notifications and the data.  For the “Set”
  8. private string helloVar;
    public string HelloVar
    {
        get => helloVar;
        set => Set(ref helloVar, value);
    }

  9. Add to the constructor a sort of pre-set to the HelloVar by adding the statement:

    HelloVar = “Hello World Bound”;
  10. That’s pretty much it for the simple data or our ViewModel.  All we need to do is bind the view model to the DataContext of the View and then bind to the property.
  11. Switch to the UserControl1.xaml.cs code behind for our user control.
  12. In the constructor after the InitializeComponent() method add
    DataContext = new UserControl1VM();
  13. If not prompted, add a using statement “WIndowsFormsApp1.ViewModels”.  Your namespace may vary depending on what you named things.
  14. All you need to do is now bind our TextBlock to the HelloVar property in our view model.  I would also suggest for fun, you change the TextBlock to be a TextBox (let’s you edit it.)

     <TextBox Text="{Binding HelloVar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
If you now start the application you should find it starts with the text you placed in the view model constructor.  You can put a breakpoint on the setter for the HelloVar property and try changing the value in the application.  You’ll know that as soon as you change the value of the TextBox the setter breakpoint is hit.


You can now add as many properties as you like to your view model and “go to town” on binding that work.  You can use the view model to load data, save it out, do all the manipulations you need.  In our next blog I’ll show you how to add commands so you can bind to business logic, like saving data.
Next –> Updating WinForms with WPF… Adding Commands.

No comments:

Post a comment