October 16, 2020—A survey of the MVVM pattern in WPF
MVVM stands for Model View View-Model. It is a pattern for creating user
interfaces. It helps you separate your view and its behavior from the rest of
your application. With some discipline that means your application will be
easier to change over time.
Model—The model is basically everything except the view and its
behavior.
View—The user interface.
View model—The view's behavior.
WPF stands for Windows Presentation Foundation. It was created by
Microsoft in the late 2000s. It helps you create visual applications for
Windows using the .Net Framework.
WPF popularized the MVVM pattern, and the MVVM pattern is very natural to use
in WPF.
A little example
Here's an example:
Let's step through Program.cs
The model is instantiated
The view model is instantiated
The view is instantiated, given the view model, and displayed to the user
Behind the scenes, the {Binding Message} has instructed WPF
to pay attention to the view model's PropertyChanged event,
especially when it raises an event with the name "Message"
In the background, some message is asynchronously acquired from the
database and assigned to the view model's Message property
When the view model's Message property is assigned it will
raise its PropertyChanged event
WPF notices the raised event and reads the Message property
from the view model and assigns it to the Text property of
the TextBlock in the view
The end result is the message is shown on the screen.
That might seem kind of convoluted. Especially if you compare with this:
But I think with the next example you'll begin to see why the convolution is
worth it.
A bigger example
Here's a more complicated example:
Let's compare it to WPF without MVVM:
Again, I think the non-MVVM way is simpler in this case. But that's not all...
Add some styling
Now let's change the label colors. In the MVVM version we'll change our views:
And in the non-MVVM version we'll change the code that generates the UI
components:
Did you catch that? In the MVVM version our changes were quite isolated. We
only changed views. We didn't change view models, nor did we alter the model,
nor did we alter how the view, view model, and model are wired together. The
chances are quite small that we introduced a bug in how data is read from or
stored to the model. We also probably didn't accidentally mess up what happens
when you click on your favorite person. The advantage is our changes were
very isolated.
But in the non-MVVM version we had to change code in close proximity to
completely unrelated things. Simple changes like changing the labels' colors
were introduced immediately next to the code that manipulates the model.
Have you ever experienced an application that's stuck with a decades-old UI
because its maintainers don't have the time to fish through the tangled mess
of UI styling and business logic? Have you ever experienced an application
that broke after its maintainers changed colors or layout? Those kinds of
things happen less often with MVVM.
MVVM is not the only way
Now that we recognize the dangers of mixing UI concerns with other
responsibilities you can probably imagine various ways to separate those
things. And you can probably imagine ways to separate those things without
using MVVM. And that's fine.
The point
The point is MVVM is a disciplined way (not the disciplined way) to
isolate UI concerns.
The downsides of the MVVM pattern in WPF include:
Lots of boilerplate code
Sometimes you have to take a pretty indirect path
WPF's binding mechanism isn't the fastest thing out there
But it brings all the benefits of separating concerns.
Disclaimer—the code on this page will not compile. It's inspirational
pseudocode that I wrote off the cuff.