Attributes-based validation in a WPF MVVM application

.Net, CodeProject, WPF No Comments »

Today, I’m proud to share with you my very first article available on CodeProject. This article presents a technique which can be used in order to add validation in a WPF MVVM application based on attribute. Basically, it means that you can write validation logic like that (notice the attribute associated to this property):

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
[Required(ErrorMessage = "Field 'FirstName' is required.")]
public string FirstName
{
    get
    {
        return this.firstName;
    }
    set
    {
        this.firstName = value;
        this.OnPropertyChanged("FirstName");
    }
}

Of course the article comes with a nice demo application:

You can read the full article here: Attributes-based validation in a WPF MVVM application


MVVM Frameworks Explorer updated

Silverlight, WPF, Windows Phone 7 Comments »

Today I’m releasing a new version of my MVVM Frameworks Explorer application. You can find the updated version here: http://www.japf.fr/silverlight/mvvm/index.html

Here is a list of the changes in this new version:

  • application updated to Silverlight 4
  • support is now detailed for WPF, Silverlight and Windows Phone
  • new frameworks added (MEFedMVVM…)
  • framework’s logo added
  • download count added (based on the information I found on CodePlex website)
  • about window

As always, feel free to give feedback :-)

Leveraging expression trees to unit test ViewModel classes

.Net, Silverlight, Tools, WPF 5 Comments »

Introduction: In this article, I’m describing a technique which leverage the expression trees of C# 3.0 in order to facilitate the unit testing of ViewModel’s properties. My final goal is to be able to unit test a ViewModel property in 1 line.

Without any doubt MVVM is now the most used framework to leverage WPF and Silverlight functionalities in the best way ! During the last Mix, 3 sessions were dedicated to this methodology (you can watch the videos online here).

As you already know one of the key advantage of the MVVM methodology is to improve the testability of the overall application by reducing the amount of code in the code-behind and producing ViewModel classes which are testable. We use to say that ViewModel classes are testable because:

  • they are not coupled to UI concepts (controls, focus, keyboard input…)
  • they can wrap model objects using interfaces (for instance a PersonViewModel wraps a IPerson object)
  • they are not subclassing a UI control (such as Button or Window)

Today I’d like to share a technique I’m using to facilitate the unit tests of some properties of my ViewModel classes.

Let’s use a very simple ViewModel class as example:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class PersonViewModel : ViewModelBase
{
  private IPerson person;
  private bool isSelected;
 
  public string Name 
  {
     get
     {
        return this.person.Name;
     }
     set
     {
        this.person.Name = value;
        this.OnPropertyChanged("Name");
     }
  }
 
  public bool IsSelected
  {
    get
    {
      return this.isSelected;
    }
    set
    {
      this.isSelected = value;
      this.OnPropertyChanged("IsSelected");
    }
  }
 
  // rest of the code omitted for simplicity
}

The Name property, as usually with the MVVM pattern gets its value from the wrapped model object. The easiest way to unit test this property is to use a mocking library. Here is a example using MOQ (my favourite mocking library):

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
[Test]
public void TestName()
{
  var mockPerson = new Mock<IPerson>();
 
  var vm = new PersonViewModel(mockPerson.Object);
 
  vm.Name = "Jeremy";
 
  // verify that the Name property of the IPerson interface has been set
  mockPerson.VerifySet(p => p.Name = "Jeremy");
}

The Selected property is different because it doesn’t wrap a model property. It’s an information that is added to the ViewModel layer in order to control a UI-related property (for example the IsSelected property of a ListBoxItem). This technique is heavily used to have ViewModel classes interact with the WPF or Silverlight TreeView or ListBox control (you can check out this excellent article of Josh Smith for more detail).

In order to unit test this property, we must:
1/ ensure the PropertyChanged event of the INotifyPropertyChanged is raised properly
2/ ensure we can write a value and read back the correct value

Here is a sample code which does this unit test:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
[Test]
public void TestName()
{
var vm = new  PersonViewModel();
bool propertyChanged = false;
 
vm.PropertyChanged += (s, e) => propertyChanged = e.PropertyName ==  "Name";
vm.Name = "newName";
 
Assert.IsTrue(propertyChanged);
Assert.AreEqual("newName", vm.Name);
}

It quickly become cumbersome to copy/paste this unit test for all the ViewModel properties we have. That’s the reason I started thinking about another way to do it…

Here is the feature I’m proposing:

?View Code CSHARP
1
2
3
4
5
6
[Test]
public void TestName()
{
var vm = new PersonViewModel();
TestHelper.TestProperty(vm, v => v.IsSelected);
}

In this sample, I’m telling I want to test the IsSelected property of the PersonViewModel type. The advantages are:
1/ less code involved : 1 line to test 1 property
2/ intellisense support in order to prevent typing error and no more “magic” string to give the name of the property
3/ refactoring the name of the property will refactor this sample code too
4/ automatic generation of default test values behind the scene

How does it works ?

  • TestProperty treats the second parameter as an Expression<Func> and not as a Func directly
  • Using expression tree (the “v => v.IsSelected” part),  I’m able to retrieve the name of the property and its type
  • Using reflection, I’m able to get and set the value
  • Depending on the type of the property (string, bool, int, double), I have default values write and read back (with a test to ensure that the PropertyChanged event has been raised properly).

Here is the code of the TestPropertyMethod:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void TestProperty<T, U>(T viewmodel, Expression<Func<T, U>> expression)
    where T : INotifyPropertyChanged
{
    if(expression.Body is MemberExpression)
    {
        MemberExpression memberExpression = (MemberExpression) expression.Body;
 
        if (expression.Body.Type == typeof(bool))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, true, false);
        }
        else if (expression.Body.Type == typeof(string))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, "value1", "value2");
        } 
        else if (expression.Body.Type == typeof(int))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1, 99);
        }
        else if (expression.Body.Type == typeof(double))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1.0, 99.0);
        }
        else
        {
            throw new NotSupportedException("Type is not supported");
        }
   }
}

And the TestViewModelProperty:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static void TestViewModelProperty<T, U>(T viewModel, string propertyName, U value1, U value2)
    where T : INotifyPropertyChanged
{
    bool propertyChanged;
    viewModel.PropertyChanged += (s, e) => propertyChanged = e.PropertyName == propertyName;
 
    propertyChanged = false;
    viewModel.SetValue(propertyName, value1);
    Assert.IsTrue(propertyChanged);
    Assert.IsTrue(viewModel.GetValue<U>(propertyName).Equals(value1));
 
    propertyChanged = false;
    viewModel.SetValue(propertyName, value2);
    Assert.IsTrue(propertyChanged);
    Assert.IsTrue(viewModel.GetValue<U>(propertyName).Equals(value2));
}

I’m using 2 extensions methods in order to get and set value from the ViewModel object using reflection. Here they are:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
private static T GetValue<T>(this object obj, string propertyName)
{
    var propertyInfo = obj.GetType().GetProperty(propertyName);
    return (T)propertyInfo.GetValue(obj, null);
}
 
private static void SetValue<T>(this object obj, string propertyName, T value)
{
    var propertyInfo = obj.GetType().GetProperty(propertyName);
    propertyInfo.SetValue(obj, value, null);
}

Please feel free to download the source code of the ViewModelTestHelper class.

Minor update to the Silverlight MVVM frameworks explorer

Silverlight, WPF 1 Comment »

Thanks to the readers who gave me feedback on my Silverlight MVVM frameworks explorer I updated the application this morning in order to fix some problems.

Here is the change set:

  • fix incorrect URLs
  • fix incorrect “Silverlight Support” options. As Laurent Bugnion said in the comments, his MVVM Light framework was the only one supporting Silverlight which was strange…
  • links now open in a new window

Click on the following image to launch the Silverlight application.

About adding new frameworks, I’m not sure to add those which targets a much larger domain than MVVM itself. CompositeApplication guidance for example is a lot more than MVVM…

Review of 2009 blog posts

General No Comments »

In the past year, I’ve posted more than 30 articles on my blog. Here is a summary of those posts (link in bold are those which got the most traffic during the year). Obviously, MVVM was a very hot topic during 2009 :-)

January

February

March

April

May

July

August

September

October

November

Discover and compare existing MVVM frameworks !

.Net, Silverlight, WPF 14 Comments »

A couple of weeks ago, I wrote a blog post where I compared the existing MVVM frameworks. This post became a bit famous in the WPF/Silverlight blog world and I received a lot of feedback to update the list, fix information, etc. I also got a request from Erik suggesting me to put all the datas in a matrix.

Today I’m proud to announce the MVVM frameworks Silverlight application (click the image to open the Silverlight3 page).

silverlight-mvvm-app

A couple of observation:

  • please contact me via this blog or twitter if you find incorrect information
  • I’m not judging anybody’s work by giving rating, it’s just my personal feeling to have an easiest way to sort the data

Hope you’ll like it :-)

A quick tour of existing MVVM frameworks

.Net, WPF 30 Comments »

[Article updated november, 26th: see my latest blog post for a better experience browsing the frameworks]

Read the rest of this entry »

How to close a View from a ViewModel ?

.Net, Events, WPF 13 Comments »

Note: I wrote this article to clarify relationships between ViewModel and View classes. If you want a complete solution you should take a look at existing MVVM framework like Cinch (by Sacha Barber).

Yesterday, there was an insteresting question about MVVM on StackOverflow: “How to close a View from a ViewModel ?”

Like always with WPF, there are many approaches to solve this problem.

Solution 1: give a reference to the View in the ViewModel

You need to control the View from the ViewModel ? Just gives a reference to the View in the ViewModel constructor.

?View Code CSHARP
1
2
3
4
public Window1()
{
  this.DataContext = new Window1ViewModel(this);
}

Unfortunatelly, this approach has several drawbacks:

  • it breaks the foundamental principle of the MVVM methodology: the ViewModel should be an abstraction of the View
  • it complicates the work needed to unit test your ViewModel
  • it introduces high coupling between the ViewModel and the View

Solution 2: the ViewModel raises an event when it wants to close its associated View

If having a reference to the View in the ViewModel is not the right thing, why not using an event. We can add a RequestClose event in the ViewModel class and raise this event when the ViewModel wants to close its associated View.

The View, when it creates the ViewModel subscribe to the RequestClose event. In the event handler, the View is closed.

?View Code CSHARP
1
2
3
4
5
6
7
8
// class is omitted, only constructor is shown
public Window1()
{
  var viewmodel = new Window1ViewModel();
  viewmodel.RequestClose += (s, e) => this.Close();
 
  this.DataContext = viewmodel;
}

Solution 2, first refinement

Of course I prefer the event based solution, but we can improve it. The first refinement we can do is to make sure the event will be coherent over all our classes. To achieve this I setup an interface:

?View Code CSHARP
1
2
3
4
public interface IRequestCloseViewModel
{
  event EventHandler RequestClose
}

This interface is implemented by my ViewModel classes which wants to support the ability to close their associated Views.

Solution 3, second refinement

Another possible refinement is to automate the subscription of the RequestClose event in the View. To do that, I created an abstract ApplicationWindowBase class that inherits from Window. When the DataContext changes, I check if the IRequestCloseViewModel is supported by the DataContext:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ApplicationWindowBase : Window
{
  public ApplicationWindowBase()
  {
    this.DataContextChanged += new DependencyPropertyChangedEventHandler(this.OnDataContextChanged);
  }
 
  private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  {
    if (e.NewValue is IRequestCloseViewModel)
    {
      // if the new datacontext supports the IRequestCloseViewModel we can use
      // the event to be notified when the associated viewmodel wants to close
      // the window
      ((IRequestCloseViewModel)e.NewValue).RequestClose += (s, e) => this.Close();
    }
  }
}

Like I said in the intro, this a very basic implementation of this concept. Many other approach exists. A good source of information is in the source code of existing MVVM frameworks.

Adding transitions to a MVVM based dialog

WPF 16 Comments »

In my last blog post about MVVM, I showed how it is natural to build a common WPF dialog using DataBinding and Templates with the Model-View-ViewModel methodology. Because I’m having a lot of feedback on posts I wrote about how transitions can be done in WPF, I decided to reuse my previous demo application and add transitions when switching from one element to another. Here is the result of the demo application:

Get the Flash Player to see this content.

I didn’t wanted to implement all the transitions, instead I decided to use the famous FluidKit library and to wrap its transition control into a reusable and “MVVM compliant” control. I thank Pavan Podila for giving me feedback while designing this control.

Basically, based on Pavan suggestions I created an INavigationAware interface and subclass transitions I wanted to reuse from FluidKit. The INavigationAware interface allows me to specify that the transition supports going forward and going backward (regarding the previous and current selection of the user in the menu).

The control itself (that I call a NavigationPresenter) is very simple, I just use 2 ContentPresenter that I switch when the Content property changes using the TransitionPresenter control from the FluidKit library. The NavigationPresenter works with 3 dependency properties:

  • GoForward (bool): to specifiy the way of the transition
  • Transition: to specify the transition to use
  • Content: to specify the content of the control

Here is the XAML for using the NavigationPresenter

1
2
3
4
5
6
7
8
9
<!-- The ContentProperty is not bound directly to the SelectedItem of the ListBox because the
     GoForward property must be updated BEFORE the content changes. The CurrentContent property
     is defined in the ViewModel class and updated everytime the selection of the ListBox changes,
     after setting up the GoForward value. -->
<NavigationTransition:NavigationPresenter 
    Content="{Binding CurrentContent}"
    Transition="{Binding ElementName=transitionComboBox, Path=SelectedItem.Tag}"
    GoForward="{Binding DataContext.GoForward, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type AnimatedContentPresenter:MainDialog}}}">            
</NavigationTransition:NavigationPresenter>

The sample application comes with 3 animations but more can be used from the FluidKit library. It’s also possible to create your own transition (inherit from Transition base class). You can download the sample application here. Hope you’ll like it !

Thinking with MVVM: Data Templates + ContentControl

.Net, WPF 12 Comments »

I’m still playing with MVVM at work and I got a new occasion to setup a dialog using the MVVM methodology.

I really love the process of creating User Interface using MVVM, the process is so much natural ! Basically, I needed to create a “setup” dialog in the application I’m currently working on. I wanted to achieve something like this:

setup-dialog

Of course, I wanted to create this dialog using the power of WPF. My primary objective when I create a new dialog is to keep the code-behind empty. Using MVVM it took me about 10 minutes to create the basic structure of the dialog withouth writting a single line of code in the xaml.cs files.

Here is the process I followed to create this dialog. This is the “thinking with MVVM” part because I’m explaining the reasoning I had :-) You can download the source code for this example here.

Setup the main dialog

When I need quick prototypes, I often don’t use Blend and type the XAML directly into Visual Studio editor. That was the very first part I did to write this XAML:

1
2
3
4
5
6
7
8
9
10
11
12
  <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
 
        <ListBox Grid.Column="0" Margin="5"/>
 
        <Border Grid.Column="1" Margin="5" BorderBrush="#FF7F9DB9" BorderThickness="1">
            <!-- Content goes here -->
        </Border>
    </Grid>

Pretty easy isn’t it. Please note the “Content goes here” comment. I knew I wanted to put the settings dialogs here, but I didn’t know how… I named this file ConfigurationDialog.xaml.

Create sub-configuration dialogs

For this example, I created 2 sub-configuration dialogs just for the demo. I just put a TextBlock into a Grid to demonstrate the principles. Of course, we should add real configuration controls such as CheckBox, TextBox, etc. Those 2 new files are GeneralSettingsView and AdvancedSettingsView and are UserControls.

Create a ViewModel class for each View

I used to use an abstract base class for all my ViewModel classes where I implement the INofityPropertyChanged interface. I also use a trick from Josh Smith to throw an exception if the property name doesn’t exist when the PropertyChanged event is raised.

That gives us 3 new files: ConfigurationDialogViewModel, GeneralSettingsViewModel and AdvancedSettingsViewModel. Because I wanted configuration dialogs to have a common Name property (to identify them in the UI), I created a base class SettingsViewModelBase.

Setup the ViewModel of the main View

I needed the main View to expose the other configuration views available. I used an ObservableCollection for that:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ConfigurationDialogViewModel : ViewModelBase
{
        private readonly ObservableCollection<SettingsViewModelBase> settings;
 
        public ObservableCollection<SettingsViewModelBase> Settings
        {
            get { return this.settings; }
        }
 
        public ConfigurationDialogViewModel()
        {
            this.settings = new ObservableCollection<SettingsViewModelBase>();
 
            this.settings.Add(new GeneralSettingsViewModel());
            this.settings.Add(new AdvancedSettingsViewModel());
        }
}

Setup the main View  to consume datas from its ViewModel

I did some changes in the XAML to databind the ListBox’s ItemsSource property to the ViewModel. Because I always set the DataContext property of a view to its associated ViewModel, there is no ambiguity:

1
ItemsSource="{Binding Settings}".

The ListBox control has no idea how a SettingsViewModelBase object (that is in the associated ObservableCollection) should be displayed. We need a simple DataTemplate to specify this information:

1
2
3
4
5
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Padding="10"/>
                </DataTemplate>
            </ListBox.ItemTemplate>

And finish using my favourite part !

We just setup a ListBox to consume a collection of SettingsViewModelBase class to build a menu, fine. By using a very simple DataTemplate, we said: “I want to render the SettingsViewModelBase object in the ListBox using a TextBlock”.

We can take this reasoning one step further. We have a View associated to each SettingsViewModelBase. ListBox was fine to have a collection of controls. How could we display only one control ?

We can use a ContentControl of course ! Because we want do display the dialog that is currently selected in the menu, we can use a simple DataBinding (here, the ListBox has been named ListBoxMenu):

1
<ContentControl Content="{Binding ElementName=ListBoxMenu, Path=SelectedItem}"/>

One more time, we got a rendering problem. The ContentControl doens’t know how to render a SettingsViewModelBase object. Well, it’s not a big deal, just specify it:

1
2
3
4
5
6
7
8
    <Window.Resources>
        <DataTemplate DataType="{x:Type ViewModel:GeneralSettingsViewModel}">
            <View:GeneralSettingsView/>
        </DataTemplate
        <DataTemplate DataType="{x:Type ViewModel:AdvancedSettingsViewModel}">
            <View:AdvancedSettingsView/>
        </DataTemplate>
    </Window.Resources>

What I’m saying here is that GeneralSettingsViewModel should be rendered using a GeneralSettingsView. That’s exactly what we need ! Because the Views are created using a DataTemplate, we do not need to setup the DataContext, it will be automatically registered to the templated object, the ViewModel.

Conclusion

The example I describe here is very simple. The goal was to show the process of creating a dialog thinking in the “MVVM” way. It was very natural to use the concepts I explain here. The code-behinds are completely empty and ViewModel classes are testable ! Because the View are XAML only, I can give them to a designer that will tweak them to make them have a nice look.

You can download the source code for this example here.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in