Adventures in MVVM – My ViewModel Base

More Adventures in MVVM Shout it kick it on DotNetKicks.com

First, I’d like to say: THIS IS NOT A NEW MVVM FRAMEWORK. I tend to believe that MVVM support code should be specific to the system you are building and the developers working on it.  I have yet to find an MVVM framework that does everything I want it to without doing too much.  Don’t get me wrong… there are some good frameworks out there.  I just like to pick and choose things that make sense for me.  As of Silveright 4, they don’t support binding to dynamic properties, so some of the capabilities are lost, but with a little hacking we can make it work.

That being said, I want to share my ViewModel base class with the world.  I have had several conversations with people about the problems I have solved using this ViewModel base.  A while back, I posted an article about some experiments with a “Rails Inspired ViewModel”.  What followed from those ideas was a ViewModel base class that I take with me and use in my projects.  It has a lot of features, all designed to reduce the friction in writing view models. I have put the code out on Codeplex under the project: ViewModelSupport.

Finally, this article focuses on the ViewModel and only glosses over the View and the Model.  Without all three, you don’t have MVVM.  But this base class is for the ViewModel, so that is what I am focusing on.

Features:

  1. Automatic Command Plumbing
  2. Property Change Notification
  3. Strongly Typed Property Getter/Setters
  4. Dynamic Properties
  5. Default Property values
  6. Derived Properties
  7. Automatic Method Execution
  8. Command CanExecute Change Notification
  9. Design-Time Detection
  10. What about Silverlight?

Automatic Command Plumbing

This feature takes the plumbing out of creating commands.  The common pattern for commands in a ViewModel is to have an Execute method as well as an optional CanExecute method.  To plumb that together, you create an ICommand Property, and set it in the constructor like so:

Before

public class AutomaticCommandViewModel
{
    public AutomaticCommandViewModel()
    {
        MyCommand = new DelegateCommand(Execute_MyCommand, CanExecute_MyCommand);
    }

    public void Execute_MyCommand()
    {
        // Do something
    }

    public bool CanExecute_MyCommand()
    {
        // Are we in a state to do something?
        return true;
    }

    public DelegateCommand MyCommand { get; private set; }
}

With the base class, this plumbing is automatic and the property (MyCommand of type ICommand) is created for you.  The base class uses the convention that methods be prefixed with Execute_ and CanExecute_ in order to be plumbed into commands with the property name after the prefix.  You are left to be expressive with your behavior without the plumbing.  If you are wondering how CanExecuteChanged is raised, see the later section “Command CanExecute Change Notification”.

After

public class AutomaticCommandViewModel : ViewModelBase
{
    public void Execute_MyCommand()
    {
        // Do something
    }

    public bool CanExecute_MyCommand()
    {
        // Are we in a state to do something?
        return true;
    }
}

 

Property Change Notification

One thing that always kills me when implementing ViewModels is how to make properties that notify when they change (via the INotifyPropertyChanged interface).  There have been many attempts to make this more automatic.  My base class includes one option.  There are others, but I feel like this works best for me.

The common pattern (without my base class) is to create a private backing store for the variable and specify a getter that returns the private field.  The setter will set the private field and fire an event that notifies the change, only if the value has changed.

Before

public class PropertyHelpersViewModel : INotifyPropertyChanged
{
    private string text;
    public string Text
    {
        get { return text; }
        set
        {
            if(text != value)
            {
                text = value;
                RaisePropertyChanged("Text");
            }
        }
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        var handlers = PropertyChanged;
        if(handlers != null)
            handlers(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

This way of defining properties is error-prone and tedious.  Too much plumbing.  My base class eliminates much of that plumbing with the same functionality:

After

public class PropertyHelpersViewModel : ViewModelBase
{
    public string Text
    {
        get { return Get<string>("Text"); }
        set { Set("Text", value);}
    }
}

 

Strongly Typed Property Getters/Setters

It turns out that we can do better than that.  We are using a strongly typed language where the use of “Magic Strings” is often frowned upon.  Lets make the names in the getters and setters strongly typed:

A refinement

public class PropertyHelpersViewModel : ViewModelBase
{
    public string Text
    {
        get { return Get(() => Text); }
        set { Set(() => Text, value); }
    }
}

 

Dynamic Properties

In C# 4.0, we have the ability to program statically OR dynamically.  This base class lets us leverage the powerful dynamic capabilities in our ecosystem. (This is how the automatic commands are implemented, BTW)  By calling Set(“Foo”, 1), you have now created a dynamic property called Foo.  It can be bound against like any static property.  The opportunities are endless.  One great way to exploit this behavior is if you have a customizable view engine with templates that bind to properties defined by the user.  The base class just needs to create the dynamic properties at runtime from information in the model, and the custom template can bind even though the static properties do not exist. All dynamic properties still benefit from the notifiable capabilities that static properties do.

For any nay-sayers out there that don’t like using the dynamic features of C#, just remember this: the act of binding the View to a ViewModel is dynamic already.  Why not exploit it?  Get over it :)

Just declare the property dynamically

public class DynamicPropertyViewModel : ViewModelBase
{
    public DynamicPropertyViewModel()
    {
        Set("Foo", "Bar");
    }
}

Then reference it normally

<TextBlock Text="{Binding Foo}" />

 

Default Property Values

The Get() method also allows for default properties to be set.  Don’t set them in the constructor.  Set them in the property and keep the related code together:

public string Text
{
    get { return Get(() => Text, "This is the default value"); }
    set { Set(() => Text, value);}
}

 

Derived Properties

This is something I blogged about a while back in more detail.  This feature came from the chaining of property notifications when one property affects the results of another, like this:

Before

public class DependantPropertiesViewModel : ViewModelBase
{
    public double Score
    {
        get { return Get(() => Score); }
        set
        {
            Set(() => Score, value);
            RaisePropertyChanged("Percentage");
            RaisePropertyChanged("Output");
        }
    }

    public int Percentage
    {
        get { return (int)(100 * Score); }
    }

    public string Output
    {
        get { return "You scored " + Percentage + "%."; }
    }
}

The problem is: The setter for Score has to be responsible for notifying the world that Percentage and Output have also changed.  This, to me, is backwards.    It certainly violates the “Single Responsibility Principle.” I have been bitten in the rear more than once by problems created from code like this.  What we really want to do is invert the dependency.  Let the Percentage property declare that it changes when the Score Property changes.

After

public class DependantPropertiesViewModel : ViewModelBase
{
    public double Score
    {
        get { return Get(() => Score); }
        set { Set(() => Score, value); }
    }

    [DependsUpon("Score")]
    public int Percentage
    {
        get { return (int)(100 * Score); }
    }

    [DependsUpon("Percentage")]
    public string Output
    {
        get { return "You scored " + Percentage + "%."; }
    }
}

 

Automatic Method Execution

This one is extremely similar to the previous, but it deals with method execution as opposed to property.  When you want to execute a method triggered by property changes, let the method declare the dependency instead of the other way around.

Before

public class DependantMethodsViewModel : ViewModelBase
{
    public double Score
    {
        get { return Get(() => Score); }
        set
        {
            Set(() => Score, value);
            WhenScoreChanges();
        }
    }

    public void WhenScoreChanges()
    {
        // Handle this case
    }
}

After

    public class DependantMethodsViewModel : ViewModelBase
    {
        public double Score
        {
            get { return Get(() => Score); }
            set { Set(() => Score, value); }
        }

        [DependsUpon("Score")]
        public void WhenScoreChanges()
        {
            // Handle this case
        }
    }

 

Command CanExecute Change Notification

Back to Commands.  One of the responsibilities of commands that implement ICommand – it must fire an event declaring that CanExecute() needs to be re-evaluated.  I wanted to wait until we got past a few concepts before explaining this behavior.  You can use the same mechanism here to fire off the change.  In the CanExecute_ method, declare the property that it depends upon.  When that property changes, the command will fire a CanExecuteChanged event, telling the View to re-evaluate the state of the command.  The View will make appropriate adjustments, like disabling the button.

DependsUpon works on CanExecute methods as well

public class CanExecuteViewModel : ViewModelBase
{
    public void Execute_MakeLower()
    {
        Output = Input.ToLower();
    }

    [DependsUpon("Input")]
    public bool CanExecute_MakeLower()
    {
        return !string.IsNullOrWhiteSpace(Input);
    }

    public string Input
    {
        get { return Get(() => Input); }
        set { Set(() => Input, value);}
    }

    public string Output
    {
        get { return Get(() => Output); }
        set { Set(() => Output, value); }
    }
}

 

Design-Time Detection

If you want to add design-time data to your ViewModel, the base class has a property that lets you ask if you are in the designer.  You can then set some default values that let your designer see what things might look like in runtime.

Use the IsInDesignMode property

public DependantPropertiesViewModel()
{
    if(IsInDesignMode)
    {
        Score = .5;
    }
}

 

What About Silverlight?

Although you cannot bind directly to dynamic properties and convention-based commands, you CAN bind using a value converter.  This little hack is explained in more detail in my next post.  Other than that slight difference, all of these features work in Silverlight just as they do in WPF.  You don’t need to code your ViewModels any differently to get it to work, which aids in the sharing of behavior between WPF and Silverlight.

 

Good to go?

So, that concludes the feature explanation of my ViewModel base class.  Feel free to take it, fork it, whatever.  It is hosted on CodePlex.  When I find other useful additions, I will add them to the public repository.  I use this base class every day.  It is mature, and well tested.  If, however, you find any problems with it, please let me know!  Also, feel free to suggest patches to me via the CodePlex site.  :)

Tags: , , ,

23 Responses to “Adventures in MVVM – My ViewModel Base”

  1. [...] to.  My goal is to get to a completely convention-based approach to commands, much like my C# ViewModel Support.  Stay [...]

  2. [...] publication that inspired this implementation was written by Brian Genisio in his article entitled Adventures in MVVM – My ViewModel Base. The implementation presented here expands upon those ideas to create a stack of view model base [...]

  1. Matt Casto says:

    I hadn’t thought of some of this, but I think I can make immediate use of it. I especially like the DependentUpon attribute.

    I’m currently using the MVVM Light Toolkit on a Silverlight 4 project, and I think I’m going to try to wrap some of this into the ViewModelBase class.

    Very nice!

  2. shahi says:

    Hi
    First of all I wanted to congradulate you for your viewmodelbase. it is great.
    I am just wondering if there is an easy way to implement from Xaml event to command
    so that we can bind event to command and its argument in view model
    like there is in the following link
    http://blog.roboblob.com/category/silverlight/
    without breaking any thing.

    Thanks
    Shahi

  3. admin says:

    Shahi:

    The ViewModelBase class does not facilitate any particular XAML-side utilities. BUT, you can use any mechanism you want to do this type of binding. In a previous post, I came up with a command behavior that you can bring into your project that lets you bind any event to commands.

    I wrote about it here: http://houseofbilz.com/archives/2009/08/27/adventures-in-mvvm-binding-commands-to-any-event/

    Good luck :)
    Brian

  4. Matt says:

    Brian,

    Just want to say that I love your view model base, I’m using it quite a bit in the program I’m writing. I’m running into a snag with commanding though. I’m using PRISM, I have the view model base in a framework DLL project attached to the solution. In a module I have a view that is having its datacontext set on the back end like so

    public Data_Selection_View(Data_Selection_ViewModel viewModel)
    {
    InitializeComponent();
    this.DataContext = viewModel;
    }
    I’m unable to get commanding to work even with this simple code

    I’m using the MyCommand code from your example.

    Any ideas?

    Thanks.
    Matt

  5. admin says:

    Matt:

    I think I’d need to see more. Does Data_Selection_ViewModel derive from ViewModelBase? I am assuming you are using C# 4.0, as it relies on dynamic properties to work. Is this WPF or Silverlight? WPF can bind to dynamic properties, but Silverlight cannot. You need to use the [MyCommand] trick that is described here for Silverlight: http://houseofbilz.com/archives/2010/05/14/adventures-in-mvvm-my-viewmodel-base-silverlight-support/. Also, it is important that your methods be prefaced with Execute_ and be public.

    Finally, have you confirmed that your DI container in PRISM is properly injecting your view model? Are you sure it is not null?

    Can you point me to an example where it is not working?

    I hope some of this helps,
    B

  6. Shailesh says:

    Hi Brian,

    Very nice viewmodel-base. There are definitely features that I want to try/use in the viewmodel-base of my current project.

    I have a question about feature 2 & 3: Strongly Typed Property Getters/Setters

    I was wondering about the implementation of this feature on performance. Isn’t this (much) slower compared to normal properties?

  7. Shailesh says:

    *implementation* = effect
    (in my previous comment, apologies)

  8. admin says:

    Shailesh: Yes, certainly, this approach is slower than a private backing store. But, not by much. It is not like you are comparing it to plain old properties. All the same stuff still needs to happen — make sure that the value is not the same, set the value and fire the event– but the difference is a Dictionary or a private field.

    When it comes down to it, though, this has never gotten in my way. The difference is negligible compared to everything else that is happening in the Silverlight UI. If you have thousands of getters/setters happening per second, it might matter, but usually that is not the case in a ViewModel.

  9. Matt says:

    Brian,

    Quick question, when using the “DependsUpon” logic, would it be possible to find out when a property of a complex object type has changed?

    So for example if on my page I have a person object and every time the “first name” property of that person object changed I want to run a method.

    Do I always have to expose that one property at my View model level? Or can I just call

    [DependsUpon("Person.FirstName")]

    If I can’t…how hard would it be to make the base class do this?

  10. admin says:

    @Matt:

    This code does not support that behavior right now, but it would be possible to enhance it. It would just be a matter of splitting on “.” and recursively calling the listen function. If you take a stab at it, let me know and I can fold it into the project.

    Along these lines, I have considered having something like a “Model” attribute that would help with stuff like this:

    [Model]
    [Expose("First")]
    [Expose("Last")]
    protected Person person;

    Any thoughts on that?

    Thanks,
    Brian

  11. Matt says:

    @Brian

    The split method would probably work best for me since I’m getting my models from RIA services.

    Where exactly would I place it in the code?

  12. Craig Richards says:

    Rad post, can’t wait ti try it out.

  13. Luigi says:

    Hi Brian,
    great idea the DependsUpon attribute.
    I was thinking that it could be improved a little bit in the performance area.
    Correct me if I’m wrong, but you are calculating the dependency map for each instance of a ViewModelBase and derived classes. As long as the map is the same for each single (derived) type, after calculating the map for an instance of the type X you could store the map for that type in a static dictionary. Next time an instance of type X is created it will reference to the same map, so you you don’t need to recalculate it, saving both memory and cpu.
    Thanks for sharing your code.
    Luigi

  14. Edward says:

    Brian, I came across your post of the VM with Dynamic Properties and this is exactly what I needed. Great Job.

  15. Great to see that I am not the only one that thinks that all those “exxtremely simple” view-models should have more functionality than they have right now.

    Most of the features you name in this blog post are already implemented in Catel (see http://catel.codeplex.com), for example:

    1) Declaring objects as model
    2) Automatic property change notification
    3) Registering callbacks
    4) Memory leak free (lots of (well-known) frameworks are full of memory leaks

    I don’t like the DependsUpon for commands. What if the developer uses 2 different parameter types? Will there be an exception, a warning, or will the method be ignored? I think that it’s not a good thing to remove the “plumbing” of commands (it’s just 2 lines of additional code, the declaration and instantation). In return of the “pluming” you can type checking and stuff is more clear for the next developer of the VM.

    What I do like very much is the Expose attribute. In Catel we already have the Model and ViewModelToModel attributes which allows you to map a property from the model to the view model. However, I really like the idea of skipping this and allowing a user to simply expose a sub property via a simple attribute.

    Thanks for the inspiration!

  16. Bryan D says:

    @Brian

    Thanks for this great helper class, the [DependsUpon] attribute is truly wonderful.

    As an exercise in learning DynamicObject and Attributes I decided to implement your idea of [Model] and [Expose("FieldName")] attributes for Properties and Fields on the ViewModel.

    I’m not exactly sure what you had in mind, my implementation tries to do the following:

    1. A [Model] attribute exposes all fields in the decorated field or property.
    2. A [Expose("FieldName"}] attribute exposes only the specified field of the decorated field or property.

    If you’re interested, I’d like to share it with you and get your opinion on my implementation.

    Thanks,
    Bryan

  17. admin says:

    Bryan,

    Yes, please! Can you start up a conversation on the CodePlex project? I’d love to see a patch or something like that and discuss it further.

    Thanks,
    Brian

  18. Just to let you know: we have implemented the Model and Expose attributes in Catel. For more information see this link:

    http://catel.catenalogic.com/index.html?exposing_properties_of_a_model.htm

    You might want to take a look at how it works. We used the ICustomTypeDescriptor to allow the dynamic objects to work, but unfortunately this only works in WPF (the interface is not implemented in Silverlight).

    Good luck!

  19. Ackroydd says:

    I think you have a typo in the first block of code, or at least a little confusion generated for beginners.
    In the paragraph preceding you mention an ICommand Property, but the code shows

    public DelegateCommand MyCommand { get; private set; }

    In the sample project it’s actually

    // public ICommand MyCommand { get; private set; }

    I know DelegateCommand actually implements ICommand so maybe it works either way (in any case it’s the not-implemented example), but it took a while to nut it out when the concepts were unfamiliar.

  20. admin says:

    @Ackroydd: Indeed, DelegateCommand implements ICommand. You can write it either way. For purposes of illustration, the difference is inconsequential.

Leave a Reply