WPF MVVM For WinForms Devs – Part 5/5

The purpose of this series of tutorials is to introduce the Model-View-ViewModel (MVVM) design pattern, and look at how to quickly and simply implement it in a Windows Presentation Foundation (WPF) application. This series is targeted at developers of all levels, but especially at developers who are looking to make the transition from Windows Forms to WPF.

This final part of the series assumes you have at least read the previous parts, or have a good working knowledge of WPF and the MVVM design pattern.

User Controls

User controls are controls that you have created for use throughout your application. Often user controls are a composite of existing WPF controls, pieced together to simplify code, improve maintainability by improving code reuse, and provide a consistent look and feel throughout your application.

In this tutorial we are going to look at how to create a date time picker as a single, unified control that accepts a DateTime object as its value.

Custom Date Picker

To make this possible, we will need to create the following;

  • Resource dictionary to store all our styles/layout behaviour (called CustomControls.xaml)
  • A class for the control behavioural logic itself (called CustomDateTimePicker.cs
  • A view and a view model for displaying and binding (called MainWindow.xaml and MainWindowViewModel.cs)

Go ahead and add the above files into your project. If you followed on from earlier parts of this post, simply stick with your existing project.

CustomDatePicker behavioural logic

Our user control is going to be a composite control that consists of a DatePicker and a ComboBox (for the times, shown in 30 minute intervals. When we provide a DateTime object to the control, it is going to split the values and display them accordingly. Likewise, when the user selects a date/time, that value is going to be reflected back to our view model.

Start by firing up the CustomDatePicker.cs file, make sure its public and inherits from UserControl. Also, ensure that the class implements the INotifyPropertyChanged interface, to ensure change notifications are created when appropriate.

public class CustomDateTimePicker : UserControl, INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

<pre><code>public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

#endregion
</code></pre>

}

Start by adding a dependency property to the control, called SelectedDateTime. This will be the property that we will bind to on our view model, to both provide data to the control, and receive data from it;

#region Dependency Properties

public static readonly DependencyProperty SelectedDateTimeProperty =
    DependencyProperty.Register("SelectedDateTime", typeof(DateTime), typeof(CustomDateTimePicker), new PropertyMetadata(GetDefaultDateTime(), Changed));

public DateTime SelectedDateTime
{
    get { return (DateTime)GetValue(SelectedDateTimeProperty); }
    set { SetValue(SelectedDateTimeProperty, value); }
}

#endregion

Amongst other things, a dependency properties accept bindings and raise their own change notifications (normal properties do not).

Next we are going to need some private methods/members.

#region Private Members

private DateTime _date;
private bool _isInternallyChanging;
private TimeSpan _time;

#endregion

#region Private Methods

private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    CustomDateTimePicker picker = d as CustomDateTimePicker;
    if (picker == null)
        return;

<pre><code>if (picker._isInternallyChanging)
    return;

DateTime dateTime = (DateTime)e.NewValue;

picker.Date = dateTime.Date;
picker.Time = TimeSpan.Parse(dateTime.ToString(&amp;quot;HH:00&amp;quot;));
</code></pre>

}

private static ObservableCollection&lt;TimeSpan&gt; GetDefaultTimes()
{
    ObservableCollection&lt;TimeSpan&gt; times = new ObservableCollection&lt;TimeSpan&gt;();

<pre><code>DateTime today = DateTime.Today;
for (DateTime time = today.AddHours(0); time &amp;lt; today.AddHours(24); time = time.AddMinutes(30))
{
    times.Add(time.TimeOfDay);
}

return times;
</code></pre>

}

private static DateTime GetDefaultDateTime()
{
    return DateTime.Parse(DateTime.Now.ToString(&quot;dd-MMM-yyyy HH:00&quot;));
}

private void SetSelectedDate()
{
    _isInternallyChanging = true;
    SelectedDateTime = new DateTime(Date.Year, Date.Month, Date.Day, Time.Hours, Time.Minutes, Time.Seconds);
    _isInternallyChanging = false;
}

#endregion

The static method Changed is a call back method that gets raised whenever the value of the dependency property gets changed. We need to keep an eye on the new value, so that whenever it changes (as long as we arent making the changes internally), we can split the value and display each part in the corresponding control. The other private methods are helper methods to populate the times combo box, get the selected date etc.

Finally, add the constructor and the public properties to ensure that the times combo box is populated and to ensure that there is a property for each control to bind to (Date and Time split parts);

#region Constructor

public CustomDateTimePicker()
{
    Times = GetDefaultTimes();
}

#endregion

#region Public Properties

public DateTime Date
{
    get { return _date; }
    set
    {
        _date = value;
        SetSelectedDate();
    }
}

public TimeSpan Time
{
    get { return _time; }
    set
    {
        _time = value;
        SetSelectedDate();
    }
}

public ObservableCollection<TimeSpan> Times { get; set; }

#endregion

The controls user interface

All we need to do now, in relation to the code for our custom control, is to design its visual appearance. This is achieved by using a style and control template.

First things first, make sure that the resource dictionary you have added in reference in the App.xaml file;

<Application.Resources>
    <ResourceDictionary Source="CustomControls.xaml" />
</Application.Resources>

Add the following code to your resource dictionary;

&lt;Style TargetType=&quot;{x:Type local:CustomDateTimePicker}&quot;&gt;
    &lt;Setter Property=&quot;Width&quot;
            Value=&quot;300&quot; /&gt;
    &lt;Setter Property=&quot;HorizontalAlignment&quot;
            Value=&quot;Left&quot; /&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;{x:Type local:CustomDateTimePicker}&quot;&gt;

<pre><code>            &amp;lt;Grid&amp;gt;
                &amp;lt;Grid.ColumnDefinitions&amp;gt;
                    &amp;lt;ColumnDefinition /&amp;gt;
                    &amp;lt;ColumnDefinition Width=&amp;quot;10&amp;quot; /&amp;gt;
                    &amp;lt;ColumnDefinition /&amp;gt;
                &amp;lt;/Grid.ColumnDefinitions&amp;gt;

                &amp;lt;DatePicker SelectedDate=&amp;quot;{Binding Date, RelativeSource={RelativeSource TemplatedParent}}&amp;quot; /&amp;gt;

                &amp;lt;ComboBox SelectedItem=&amp;quot;{Binding Time, RelativeSource={RelativeSource TemplatedParent}}&amp;quot;
                            ItemsSource=&amp;quot;{Binding Times, RelativeSource={RelativeSource TemplatedParent}}&amp;quot;
                            Grid.Column=&amp;quot;2&amp;quot; /&amp;gt;

            &amp;lt;/Grid&amp;gt;

        &amp;lt;/ControlTemplate&amp;gt;
    &amp;lt;/Setter.Value&amp;gt;
&amp;lt;/Setter&amp;gt;
</code></pre>

&lt;/Style&gt;

Lets look closely and what we have here. We have basically created a style that targets our user control. Our user control (as it inherits from UserControl) has a property called Template, which contains the layout logic itself. (Technically, the Template property lives on the Control object, which UserControl itself inherits from).

The Template property expects a control template, which we have given it. And inside the control template is simply the layout for our control. You see we have added a grid, the date picker and the combo box itself.

Notice that the bindings back to the CustomDateTimePicker file are a little different that usual. Instead we use either a TemplateBinding (rather than a standard Binding) or a standard binding with the relative source pointing back to the public property. TemplateBinding only works with dependency properties.

Consuming our custom control

To consume the user control, rather bind a value to it, start by adding a property to your view model (called SelectedDateTime) and give it a default value in the constructor;

public MainWindowViewModel()
{
    SelectedDateTime = DateTime.Now;
}

public DateTime SelectedDateTime { get; set; }

Now flip over to the xaml, and add the control;

<local:CustomDateTimePicker Grid.Column="1"
                            SelectedDateTime="{Binding SelectedDateTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Summary

There are many ways to create custom controls in WPF. We have seen one approach here where we create a code file that inherits from UserControl and and we define the layout for that control in a resource dictionary.

Download source code

I hope you enjoyed this mini series of introductory WPF MVVM tutorials.

WPF MVVM For WinForms Devs – Part 4/5

The purpose of this series of tutorials is to introduce the Model-View-ViewModel (MVVM) design pattern, and look at how to correctly implement it in an Windows Presentation Foundation (WPF) application. This series is targeted at developers of all levels, but especially at developers who are looking to make the transition from Windows Forms to WPF.

Events in Windows Forms applications

Assuming you have come from a Windows Forms background, regardless of what design patterns (if any?) you used, there is a good chance you are familiar with doing either or both of the following;

  • Double click a control (for example a button) to generate the event handler in the code behind;
private void button1_Click(object sender, EventArgs e)
{
}

or subscribe to the click event in the constructor, as follows;

public Form1()
{
    InitializeComponent();
    button1.Click += button1_Click;
}

private void button1_Click(object sender, EventArgs e)
{
}

Well, as you know code behind is not permitted in MVVM, so where do we go from here?  Well events pretty much don’t exist in MVVM.  This is quite a bold statement, but in reality you will very rarely need to subscribe to and unsubscribe from events in the “traditional” way.

This is somewhat of an over-generalisation because when you come to design user controls, you inevitably end up hooking into events as code behind is allowed in this scenario… and it can be “just easier” to subscribe to events.

Prism

We haven’t yet spoken about Prism, what it is and why you should care.  Prism (also known as the Microsoft Enterprise Library (Aka Patterns & Practices library)) provides lots of out of the box functionality to help make MVVM possible.  One feature is the Event Aggregator, which provides a mechanism for weakly subscribing to and unsubscribing from events in a safe way that avoids memory leaks.

Prism is out of the scope of this set of tutorials, but I recommend reading the MSDN documentation on how this works.

Commands

Commands are the WPF equivalent of reacting to user instigated interactions.  Commands are to WPF what Events are to WinForms.  Commands can be implemented in ways that make them reusable throughout your entire application, even across modules.

There are two approaches to create commands.  Firstly, you could create a new class and implement the ICommand interface.  The ICommand interface exposes the following;

  • CanExecute method (returns true if its OK to execute the actual command)
  • CanExecuteChanged event handler  (controls can and do subscribe to this to determine if the CanExecute value has changed)
  • Execute (called when the user actually wants to execute the command)
public class ClickCommand : ICommand
{
    #region ICommand Members
    public event EventHandler CanExecuteChanged;

<pre><code>public bool CanExecute(object parameter)
{
    return true;
}

public void Execute(object parameter)
{
    MessageBox.Show(&amp;quot;Clicked&amp;quot;);
}
#endregion
</code></pre>

}

This command will normally be used with UI elements by binding it to the Command property, which is available on many user input controls.

So that we can bind from our UI, add a property to your view-model of type ClickCommand;  (don’t forget to initialise the command in the constructor!)

public MainWindowViewModel()
{
    ClickCommand = new ClickCommand();
}

public ClickCommand ClickCommand { get; set; }

We can now bind this command to a control on our UI, in this case a Button;


<pre><code>&amp;lt;button Content=&amp;quot;Save&amp;quot;
        Command=&amp;quot;{Binding ClickCommand}&amp;quot; /&amp;gt;
</code></pre>

This is a good approach, but imagine this scenario;

You are creating a medium sized/large application that has lots of views/view-models.  You want to add a Save button to various views which, when clicked, persists some data to a database.  The actual data saved will vary between view-models.

Well a single ClickCommand isn’t going to help you here, because the code is too generic.


DelegateCommand and RelayCommand

DelegateCommand and RelayCommand are openly available, generic implementations of ICommand.  These implementations are not (yet!) implemented in the .NET framework… so fire up your favourite search engine and you should be able to find a wide variety of implementations for both.

Here is a simple version of DelegateCommand that I sometimes use. Notice that this example is not generic, meaning you have to cast from object to your target type. There are generic implementations widely available.

public class DelegateCommand : ICommand where T : class
{
    protected bool _isEnabled = true;
    private readonly Action _execute;
    private readonly Predicate _canExecute;

<pre><code>public event EventHandler CanExecuteChanged;

public DelegateCommand(Action execute, Predicate canExecute = null)
{
    _execute = execute;
    _canExecute = canExecute ?? (t =&amp;gt; _isEnabled);
}

public bool CanExecute(object parameter)
{
    return _canExecute((T)parameter);
}

public void Execute(object parameter)
{
    _execute((T)parameter);
}

public void RaiseCanExecuteChanged()
{
    var handler = CanExecuteChanged;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}
</code></pre>

}

Your view-model would look something like this;

public class MainWindowViewModel : BaseViewModel
{
    private string _myString;

<pre><code>public DelegateCommand&amp;lt;object&amp;gt; ClickCommand { get; set; }

public MainWindowViewModel()
{
    ClickCommand = new DelegateCommand&amp;lt;object&amp;gt;(OnClick, CanClick);
}

public string MyString
{
    get { return _myString; }
    set
    {
        _myString = value;
        OnPropertyChanged();
        ClickCommand.RaiseCanExecuteChanged();
    }
}

private void OnClick(object parameter)
{
    MessageBox.Show(&amp;quot;You clicked the button!&amp;quot;);
}

private bool CanClick(object parameter)
{
    return !string.IsNullOrEmpty(MyString);
}
</code></pre>

}

It becomes the responsibility of the view-model to decide what to do when the user clicks the button on your UI. To bind a button to the command, add a button as follows;

<Button Content="Click Me!"
        Command="{Binding ClickCommand}"/>

Summary

Unlike WinForms, there is not much of a concept of events in WPF. You could use the EventAggregator, which is part of the Enterprise Library from Microsoft, to subscribe to and unsubscribe from events in a weak way (a way that prevents memory leaks). Instead, we use commands, which enable use to write code that is highly reusable across our applications. Generic implementations of commands, such as DelegateCommand and RelayCommand, enable us to tailor code to specific view-models where appropriate.

WPF MVVM For WinForms Devs – Part 3/5

The purpose of this series of tutorials is to introduce the Model-View-ViewModel (MVVM) design pattern, and look at how to correctly implement it in a Windows Presentation Foundation (WPF) application. This series is targeted at developers of all levels, but especially at developers who are looking to make the transition from Windows Forms to WPF.

Capturing user input

In the previous walkthrough we; set up our view model, bound it to the view, and added a property for our model class.  We then displayed a customer name on the UI.

Let’s go ahead and make this slightly more interactive.  We want to expand our UI so that user can go ahead and update the customer details.

Update your code to the following;

&lt;Window x:Class=&quot;CustomerPortal.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local=&quot;clr-namespace:CustomerPortal&quot;
        Title=&quot;MainWindow&quot;
        Height=&quot;140&quot;
        Width=&quot;350&quot;&gt;
    &lt;Window.DataContext&gt;
        &lt;local:MainWindowViewModel /&gt;
    &lt;/Window.DataContext&gt;

<pre><code>&amp;lt;Grid Margin=&amp;quot;10&amp;quot;&amp;gt;
    &amp;lt;Grid.RowDefinitions&amp;gt;
        &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot; /&amp;gt;
        &amp;lt;RowDefinition /&amp;gt;
        &amp;lt;RowDefinition /&amp;gt;
    &amp;lt;/Grid.RowDefinitions&amp;gt;
    &amp;lt;Grid.ColumnDefinitions&amp;gt;
        &amp;lt;ColumnDefinition /&amp;gt;
        &amp;lt;ColumnDefinition /&amp;gt;
    &amp;lt;/Grid.ColumnDefinitions&amp;gt;

    &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;
                Grid.ColumnSpan=&amp;quot;2&amp;quot;
                VerticalAlignment=&amp;quot;Center&amp;quot;
                HorizontalAlignment=&amp;quot;Center&amp;quot;
                Margin=&amp;quot;10&amp;quot;&amp;gt;
        &amp;lt;TextBlock Text=&amp;quot;The customers name is:&amp;quot;
                   Margin=&amp;quot;0,0,5,0&amp;quot; /&amp;gt;
        &amp;lt;TextBlock Text=&amp;quot;{Binding Customer.LastName, Mode=OneWay}&amp;quot; /&amp;gt;
        &amp;lt;TextBlock Text=&amp;quot;,&amp;quot;
                   Margin=&amp;quot;0,0,5,0&amp;quot; /&amp;gt;
        &amp;lt;TextBlock Text=&amp;quot;{Binding Customer.FirstName, Mode=OneWay}&amp;quot; /&amp;gt;
    &amp;lt;/StackPanel&amp;gt;

    &amp;lt;TextBlock Text=&amp;quot;First Name:&amp;quot;
               Grid.Row=&amp;quot;1&amp;quot;/&amp;gt;

    &amp;lt;TextBox Text=&amp;quot;{Binding Customer.FirstName}&amp;quot;
             Grid.Row=&amp;quot;1&amp;quot;
             Grid.Column=&amp;quot;1&amp;quot; /&amp;gt;

    &amp;lt;TextBlock Text=&amp;quot;Last Name:&amp;quot;
               Grid.Row=&amp;quot;2&amp;quot; /&amp;gt;

    &amp;lt;TextBox Text=&amp;quot;{Binding Customer.LastName}&amp;quot;
             Grid.Row=&amp;quot;2&amp;quot;
             Grid.Column=&amp;quot;2&amp;quot; /&amp;gt;
&amp;lt;/Grid&amp;gt;
</code></pre>

&lt;/Window&gt;

The UI should now look something like this;

Updated UI

Let’s take a moment to review the behaviour…go ahead and make changes to the First Name and Last Name text boxes.  You will notice that when the text box loses focus, the Customers Name label is updated with the new values.  I can also assure you that the underlying model is also being updated to reflect these changes.

An unexpected situation

This works because the UI is instigating the update.  The user is making a change to a control which is bound to our model, and WPF knows to push this change to the model for us automatically.  So what happens when we instigate the change from our model class?  Take the following code;

protected override void AfterDelayElapsed()
{
    Customer.FirstName = "Bob";
    Customer.LastName = "Smith";
}

The above method (which is located in our MainWindowViewModel class) runs after a period of time (in this case 10 seconds) has elapsed.  Its reasonable to assume that because we have a TwoWay binding to the property on our view, the view should just be updated automatically.  This is not the case.

When making changes to your model classes, you have to inform the runtime that said property has changed.  This practice is known as raising change notifications in WPF. (and is arguably the vein of every WPF developers life).  There are several approaches you can take for raising change notifications, and they all start in the same way.

  • Your class must implement the INotifyPropertyChanged interface (System.ComponentModel.INotifyPropertyChanged).  This can be either on the individual class itself, or on a base class (the recommended approach)
  • The above interface provides an event that must be called, passing in the name of the property that has changed.

Base Classes Are Your Friend

I highly recommend that instead of implementing INotifyPropertyChanged directly on all of your model and view-model classes, you create a base class (called for example; BaseNotification or BaseViewModel or BaseModel) and implement the interface on there instead.  Then it is customary to have a protected method that actually takes care of raising the event.

First example implementation:

public class BaseNotification : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

<pre><code>protected virtual void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
</code></pre>

}

Using this first approach, you will need to convert all your automatic properties on your model/view-model classes to properties with backing fields (full blown properties) and raise the OnPropertyChanged method passing in the name of the property.

For example;

public class Customer : BaseNotification
{
    private string _firstName;
    private string _lastName;

<pre><code>public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        OnPropertyChanged(&amp;quot;FirstName&amp;quot;);
    }
}

public string LastName
{
    get { return _lastName; }
    set
    {
        _lastName = value;
        OnPropertyChanged(&amp;quot;LastName&amp;quot;);
    }
}
</code></pre>

}

This approach is less than ideal because we effectively have magic strings in our code, and this is bad.  Not wrong, but bad.

If you are using the .NET Framework 4.5, you can easily eliminate the magic string by adding the CallerMemberName attribute to the the PropertyName parameter on your OnPropertyChanged method.

protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Note that the CallerMemberName attribute requires that the PropertyName parameter is an optional parameter.

So with this in mind, a property on our model class would now look like this;

public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        OnPropertyChanged();
    }
}

Don’t forget to add the using statement at the top of the file;

using System.Runtime.CompilerServices;

A Better Way

You’re in luck, there is one final way to resolve this nuisance…and we need to take a second to thank the open source community for this one.  Whilst there are several packages available, I am particularly fond of PropertyChanged.Fody … a free & open source project hosted on NuGet.

Package Manager Console

From a (very!) high level, this tool (and tools like it) convert your automatic properties into properties with backing fields and inject the OnPropertyChanged method call for you…all at compile time! (hold for applause)

So as long as your class either implements INotifyPropertyChanged directly, or gets it from a base model class, your work is done.


Summary

We can easily update the model from our view thanks to two way bindings, however when updating our model we need to notify the runtime that the property has changed…this is known as change notifications.  There are two main approaches to raising change notifications; implement INotifyPropertyChanged and raising the PropertyChanged event manually using a variety of techniques, or using a third party compile time tool to do this for us.

Next we will look at Events and Commands in WPF.

Revisions

Updated 26/6/13 – Altered description of CallerMemberName. Thanks Leom Burke!

WPF MVVM For WinForms Devs – Part 2/5

The purpose of this series of tutorials is to introduce the WPF MVVM (Model-View-ViewModel) design pattern, and look at how to correctly implement it in an Windows Presentation Foundation (WPF) application. This series is targeted at developers of all levels, but especially at developers who are looking to make the transition from Windows Forms to WPF.

How to quickly implement MVVM in your C# WPF application

Start by firing up an instance of your favourite version of Visual Studio (free or paid) and create a new WPF application, call it CustomerPortal.

VS Create Project Dialog

Add a new class to your project, called Customer.  This will be your model class.  Add the following code;

public class Customer
{
public int Id { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public DateTime DateOfBirth { get; set; }
}

Now create your view model class…remembering that the view-model is responsible for presenting the data within the model to the view.  Add the following code;

public class MainWindowViewModel
{
public MainWindowViewModel()
{
Customer = new Customer
{
DateOfBirth = DateTime.Parse("1970-01-01"),
FirstName = "Jon",
LastName = "Preece",
Id = 1
};
}

public Customer Customer { get; set; }

public string FullName
{
get
{
if (Customer == null)
return string.Empty;

return string.Format("{0}, {1}", Customer.LastName.ToUpper(), Customer.FirstName);
}
}
}

In this example, we are creating an instance of the model directly in the constructor (for simplicity). Typically this information would be retrieved from an external data source.

Finally, we need to let the view know about the view-model so that we can display the model data.  Edit the XAML in MainWindow.xaml so that it looks like this;

<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>

If you are unable to compile at this stage, check that the ‘local’ namespace (xmlns:local) matches the namespace your view-model class sits in.

For example:

xmlns:local="clr-namespace:CustomerPortal"

Finally, we’re ready to present the value of our FullName property to the user.  Replace the Grid in your view with the following code;

<StackPanel Margin="10"
Orientation="Horizontal">
<TextBlock Text="The customers name: " />
<TextBlock Text="{Binding FullName}" />
</StackPanel>

In the above sample, we have used data binding to retrieve the value of the property FullName from the views data context (our view model).

If you run the application, you should now see the following;

Main Window

Summary

We have seen how we can implement the MVVM design pattern in our application with very little effort.  We’ve seen the role played by the view-model.

We have not yet discussed how we get data back from the view to the model and the role of change notifications.  We will explore these topics and more in the next post.

Download  Download Source Code

WPF MVVM For WinForms Devs – Part 1/5

The purpose of this series of tutorials is to introduce the WPF MVVM (Model-View-ViewModel) design pattern, and look at how to quickly and simply implement it in a Windows Presentation Foundation (WPF) application.  This series is targeted at developers of all levels, but especially at developers who are looking to make the transition from Windows Forms to WPF.
The first part of this series will focus on;

  • What exactly is MVVM, and why should I care?
  • What problem does the MVVM design pattern attempt to solve?

Subsequent posts will attempt to;

  • Demonstrate how to quickly implement the MVVM pattern in a new WPF application.
  • Discuss data binding, change notifications, events and commands.
  • Discuss some techniques for converting older WinForms applications to WPF.
  • Discuss and see how to create user controls/custom controls without breaking the MVVM pattern.

So what is Model-View-ViewModel (MVVM)?

From a high level, MVVM is a design pattern.  MVVM provides a way for you to structure your code in a way that promotes maintainability, reusability and scalability.  This is primarily achieved by separating code into focused sections, a technique known as Separation of Concerns (S0C).

Separation of Concerns is the idea that your business logic, view (UI) specific logic and data access code should be decoupled from each other.  For example; the view should not know anything about how data is retrieved from an external data source… likewise in the case of N-tier architecture (client/server) applications, the server side code should know nothing of how data that has been retrieved is going to be visually represented to the user.

MVVM Simplified

The above is certainly an oversimplification, but it shows how the different entities interact with each other.  The model class is populated from an external data source, typically a relational database (such as SQL Server or Oracle Database).  The model is wrapped by the view-model, which prepares the data for presentation to the view.  The view-model also handles passing the data back to the model class in the event that the data has changed (i.e. the user edited a value using a text box on the UI).  The view presents the data to the user.

Maintainability, Reusability and Scalability

MVVM really comes into its own in large (typically Enterprise) applications where many developers are working on a single product.  However, MVVM is quick and simple to implement and can be beneficial to even the smallest and simplest of applications…especially those that will grow and evolve over time.

As MVVM provides a consistent approach to writing and structuring code… additional developers can come in and start working on specific areas/modules without having to learn the intricate architectural details (and quirks! :)).

Summary

In short, MVVM is a design pattern that can help small applications grow into large applications by providing consistency.  Consistency makes code more maintainable by a team of developers that my increase in numbers over time.

In the next part of the series, we will look at how we go about creating a very simple WPF application with the MVVM design pattern and we will look at what role data binding plays in making this possible.