Skip to content
Aug 18 10

Quick introduction to MVVM design pattern for WPF

by Samuel Moura

This is a small introduction to quickly get you started with M-V-VM (Model-View-ViewModel). I basically introduce it in a very straight forward fashion so that you can apply it on your own.

What is M-V-VM?

The Model-View-ViewModel is a pattern presented by John Gossman back in 2005 to solve the problem of decoupling the View from the Model, so that Views can be implemented by designers instead of software developers.

From a TDD standpoint it is also useful to have Views separated from ViewModels, this way we can TDD our ViewModels and leave a thin layer of untested code which represents only the View.

For all this, MVVM makes you think more on what you are developing helping you develop better Software.

As a side note please keep in mind that although specifically targeting WPF applications this pattern can successfully be used with other Frameworks.

The actors in MVVM

Before proceeding lets see what each what each of the MVVM intervenients represent. This is a simple illustration on how they relate to each other:

image

The Model: represents the data and business logic. It should represent your business (domain) and it should not be aware by anyway of your UI.

The View: this is the UI – the bridge between your software and its users. Normally the View is only aware of the ViewModel but there might be cases in which it may make sense to expose the Model directly to it.

The ViewModel: this is the way you connect your model to a specific View. See it has code that massages your Models in a way that the View can consume. The ViewModel should be View agnostic as the Model should.

Using MVVM in WPF

MVVM in WPF relies heavily on WPF’s excellent binding capabilities. Assuming that your Models are in place, in order for you to implement the MVVM pattern your will have to add a ViewModel class to your application as well as a View.

You then have to guarantee that when you use your View, its DataContext is the ViewModel, you can accomplish this in two ways:

  • DataTemplate: in this scenario a DataTemplate is created for the ViewModel that resolves to the View. When an instance of the ViewModel is added to the LogicalTree and it is resolved the DataTemplate will be applied to it.
  • Binding: this is achieved by directly binding the View’s DataContext to an instance of the ViewModel;

For the upcoming examples lets suppose we have the following ViewModel:

public class CustomerDetailViewModel : ViewModelBase
{
public Bitmap Picture { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}

Most of the ViewModel is cut on purpose to keep things simple (remember that properties should issue a PropertyChanged event when changed).

View-ViewModel wiring through DataTemplates

With this method you rely on the DataTemplate mechanism to map a View to whatever ViewModel it finds when WPF is applying templates to your LogicalTree.

You have to create a DataTemplate that visually represents your ViewModel setting its DataType to your ViewModels type:

<DataTemplate DataType="{x:Type local:CustomerDetailViewModel}">
	<StackPanel>
		<Image Source="{Binding Picture}"/>
		<TextBox Text="{Binding Name}"/>
		<TextBox Text="{Binding Address}"/>
	</StackPanel>
</DataTemplate>

This is particularly useful for controls that end up being added to an ItemsControl. It should not be used on a regular basis for every ViewModel.

View-ViewModel wiring through direct Binding

In this scenario you instantiate your Views directly on your WPF Windows / UserControls and bind their DataContext property to an instance of the ViewModel, created on the Windows / UserControl’s ViewModel (UI composition).

You can start by creating a UserControl as your View assuming that the DataContext will be the corresponding ViewModel:

<UserControl x:Class="MvvmIntroduction.CustomerDetailView" (...)>
	<StackPanel>
		<Image Source="{Binding Picture}"/>
		<TextBox Text="{Binding Name}"/>
		<TextBox Text="{Binding Address}"/>
	</StackPanel>
</UserControl>

Then instantiate this View where you require it:

<Window x:Class="MvvmIntroduction.MainWindow" (...)>
	<local:CustomerDetailView DataContext="{Binding CustomerDetailViewModel}"/>
</Window>

In this case the MainWindow ViewModel exposes a property of type CustomerDetailViewModel that is then attached to the CustomerDetailView through its DataContext.

This is probably how you will do most of the wiring. Having an IoC container that instantiates your ViewModels, you then expose these as properties or set them as DataContext’s of you Window / UserControls.

Final thoughts

I have been working with MVVM for the past couple of years in a day-to-day basis and can vigorously state that this is an extraordinary pattern that makes life a lot easier when developing large WPF applications.

Of course that developing larger applications makes you rethink MVVM and find ways that make it easier to work with, I will leave that for future posts though!

Thank you so much for reading. Stay tuned for more on the MVVM pattern!

Aug 13 10

Creating a Printer selection ComboBox with default printer

by Samuel Moura

In this quick tutorial I will show you how to create a ComboBox that lists all the printers installed on your computer and automatically selects the default printer.

image

In my case I had to setup such ComboBox so that a tool which users can occasionally execute, can be configured on the application I am currently working on.

In this tutorial I am assuming you are knowledge about .NET, c#, WPF and the MVVM pattern.

1. Retrieving the list of installed printers in .NET

Getting a list of installed printers is quite easy in .NET. You just have to use the PrinterSettings class on your ViewModel as follows:

public PrinterSettings.StringCollection InstalledPrinters
{
   get
   {
      return PrinterSettings.InstalledPrinters;
   }
}

Now you can directly bind the ItemsSource of your ComboBox to this collection:

<ComboBox ItemsSource="{Binding InstalledPrinters}"/>

Since this is a StringCollection exposed by a static class you can use static markup to directly bind your ComboBox to the PrinterSettings class:

<ComboBox ItemsSource="{x:Static Printing:PrinterSettings.InstalledPrinters}"/>

2. Setting the default printer selected

The first time you show your installed printers ComboBox you will probably wish to select the DefaultPrinter as your default. For this you have to actually instantiate the PrinterSettings class:

public string SelectedPrinter { get; set; }

MyViewModel()
{
   var printerSettings = new PrinterSettings();
   SelectedPrinter = printerSettings.PrinterName;
}

And that’s it, you now have a ComboBox with the list of printers. I hope this helps!

Conclusion

It should be pretty straight forward to create a special kind of control (PrinterComboBox) that encapsulates all this stuff and can be reused within your XAML.

Feb 6 10

RhinoMocks Stub not retaining value when property shadowed on inheriting interface

by Samuel Moura

I cannot remember having a Sprint like this! First the issue with debugging in VS2008 on Windows7 x64, then the issue with BadImageFormatException throwing when inheritance constraints were applied to a generic method, and now this one!

The Problem

I was still fixing the tests that had failed after upgrading to Castle.Windsor 2.1 and RhinoMocks 3.6 when I stumble on this one. Basically I had a unit test that passed before I upgraded and as soon as I switched to using the most recent versions of both libraries the test failed.

The issue manifested on a stub for an Interface that inherited from another interface re-implementing a property member with the keyword new (not a recommended approach but necessary because we were handling legacy code). Here is an example of how our interfaces are designed:

public interface INamedObject
{
   string DisplayName {get;set;}
}

public interface IFeature : INamedObject
{
   new string DisplayName {get;set;}
}

There is a base interface that implements a property which is being shadowed by the inheriting interface.

At some point in our unit test we need to access DisplayName by its base interface INamedObject. Something like the following:

[TestMethod]
public void TestMethodThatFails()
{
     var feature = MockRepository.GenerateStub<IFeature>();
     feature.DisplayName = "some name";

     Assert.AreEqual("some name", feature.DisplayName);
     Assert.AreEqual("some name", ((INamedObject)feature).DisplayName);
}

It seems that in the previous Castle.DynamicProxy implementation the proxy created for such interface would result in DisplayName being available on both base interface and inheriting interface. With the new version, when we try accessing DisplayName after casting the object to INamedObject we get a null value. The only way to access it is through the inheriting interface.

It is my understanding that this is not the expected behavior for a stub. I would expect it to retain the value as a regular class does when it implements IFeature.

A workaround

In the end I had to explicitly set DisplayName value on feature by previously casting it to INamedObject, likewise:

 [TestMethod]
 public void TestMethodThatPasses()
 {
     var feature = MockRepository.GenerateStub<IFeature>();
     feature.DisplayName = "some name";
     ((INamedObject)feature).DisplayName = "some name";

     Assert.AreEqual("some name", feature.DisplayName);
     Assert.AreEqual("some name", ((INamedObject)feature).DisplayName);
 }

It is true that we need to keep up with the evolution of libraries we consume in our projects, but has more tests are created the price we have to pay for this inconsistencies between versions of the same library starts to raise. It is always up to us to assure that the effort is worth it, and in this case, now that I have migrated all the tests, it was not that bad after all. :)

Feb 6 10

BadImageFormatException when debugging interface mocked with RhinoMocks

by Samuel Moura

My last couple of days has been quite hilarious. First there was the issue with not being able to set breakpoints on my tests, and then started having tests that failed one way when executed normally and a different way when I ran them with debugger attached!

The Problem

Recently I updated the project I am working on to Castle.Windsor version 2.1. Since we are using an abstraction over the container (for resolving purposes only), we had to adapt it to conform with the new restrictions for Resolving dependencies, thus:

public interface IFaroContainer
{
    object Resolve(Type type);
    object TryResolve(Type type);
    IEnumerable ResolveAll(Type type);
    void RegisterTypeIfMissing<TI, T>(bool registerAsSingleton)                               where T : class, TI;
    object BuildUp(Type type);
}

With the new Castle.Windsor version we have to enforce that our T class implements TI, which makes perfect sense and helps reducing erroneous registration issues that one could perform.

The problem is that when we try to Mock this interface (I am currently using RhinoMocks v3.6) while in debug mode we get a BadImageFormatException:

The problem is that there is a bug in the System.Reflection.Emit

implementation which cause the runtime to emit invalid code for this

scenario.

You can read more here.

How I fixed my issue

Since I am depending on third party lib Castle.Windsor, I cannot change the way the fluent interface is designed. It seems though that this constraint is enforced only by Castle.Windsor’s fluent interface, if you use standard component registration you will be able to bypass that argument check thus not unleashing the Emit bug.

I just changed my registrations from using the fluent interface to use the traditional AddComponent and the tests started passing!

Feb 1 10

Why breakpoints do not get hit when targeting x86 on Windows 7 x64?

by Samuel Moura

This is a very particular scenario. It happened to me and cost me over 3 hours to fix it.

Background

I am currently working on a fully managed WPF application, that references a certified C# DLL that was purposely compiled targeting x86 platform (part of the certification process I think). Since I recently got an upgrade on my development machine, and I wanted to take full advantage of my 8GB of RAM I ended up installing Windows 7 x64.

Because of the particular x86 certified DLL, I had to force my application to run in a 32bit process, thus, I changed my application build target to x86. This was about one week ago.

Since I am in the middle of a code cleanup and refactoring work item, I did not had the need to debug my source up until three days after I changed that setting, thus moving if to a back drawer on my brain.

Now I get to a point where I actually need a breakpoint, set it on my code, and run my application. The breakpoint does not get it! I then move the breakpoint to the first line of code on my App.xaml.cs constructor. It does not get hit either. Then I rebuild my project, cleanup my bin and obj folders (something could be inconsistent with those files).

Got it working

After spending a couple of hours on this, even getting older change sets to see if the issue was a problem with the source code, I re-opened that back drawer and remembered to try to set the target CPU back to any (it would only crash when the actual certified DLL was loaded).

The breakpoint finally got hit!

The solution

Obviously this did not make any sense. Since I had elaborated on the issue I was now able to successfully search for what I needed: “vs2008 breakpoint x64 target x86” and this came out as a result:

Debugging x86 application on Windows 7 x64

What happens is that when you install Visual Studio 2008 on Windows 7, the OS will set the compatibility mode to “Windows XP SP3”. All you have to do is to change this setting to “Windows Vista SP2” and your problem will be fixed. :S

Jan 31 10

Why does the DependencyProperty I set using a DataTrigger does not get its value?

by Samuel Moura

This is a common mistake when developing WPF applications. It has happened to me countless times and I have seen people asking questions about it many times.

The Problem

I have a Style which defines a DataTrigger to change some property on a control based on a bounded value from the ViewModel. Let’s take a look at this example view XAML (I have removed irrelevant source code):

(...)
<Style x:Key="{x:Type Border}" TargetType="{x:Type Border}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding BuildStatus}" Value="Ok">
            <Setter Property="Background" Value="Green"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding BuildStatus}" Value="Broken">
            <Setter Property="Background" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
(...)
<Border HorizontalAlignment="Center" VerticalAlignment="Center"
        Width="64" Height="64" Background="Transparent"
        BorderBrush="Black" BorderThickness="1,1,1,1" />
(...)

So we have a DataTrigger that changes the Background color of a Border accordingly to a BuildStatus property on our ViewModel. We do not want any color up until the ViewModel actually gets the build status, so we set the Border’s Background to Transparent. We then add a Button that can be used to toggle between two possible build status (ok and broken).

After we tie our View and its corresponding ViewModel displaying it on a window this is how our application looks when it is launched:

clip_image002

If you click on the change color Button you will see that, although we have specified our DataTriggers to change the color upon changes made to the build status nothing will happen to the build status indicator. Why is this happening?

The solution

The problem is that by setting the transparent color directly on the Border tag corresponding to the initial state color you override any value that may be set from the Style. So, in order for DataTrigger changed properties actually get set on your control you have to specify the default values on the Style through a property setter and not on the actual control instantiation:

(...)
<Style x:Key="{x:Type Border}" TargetType="{x:Type Border}">
    <Setter Property="Background" Value="Transparent"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding BuildStatus}" Value="Ok">
            <Setter Property="Background" Value="Green"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding BuildStatus}" Value="Broken">
            <Setter Property="Background" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
(...)
<Border HorizontalAlignment="Center" VerticalAlignment="Center"
        Width="64" Height="64"
        BorderBrush="Black" BorderThickness="1,1,1,1" />
(...)

In order to fix this issue, changes were made to lines: 3 and 15.

You can download a working copy of this sample by following this link.