Geeks With Blogs

News Locations of visitors to this page

Brian Genisio's House of Bilz

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.  :)

Posted on Saturday, May 8, 2010 1:07 PM | Back to top


Comments on this post: Adventures in MVVM – My ViewModel Base

# re: Adventures in MVVM – My ViewModel Base
Requesting Gravatar...
Thank you for sharing these ideas Brian - I will probably incorporate some of these ideas in my BaseViewModel class.

David
Left by David Roh on May 16, 2010 8:50 PM

# re: Adventures in MVVM – My ViewModel Base
Requesting Gravatar...
Hi Brian, just discovered your blog. Nice write-up on the MVVM base model. I especially liked the "before" and "after" code segments to help from injuring my brain cells.. :)
Left by mikekidder on Jun 07, 2010 4:20 PM

# re: Adventures in MVVM – My ViewModel Base
Requesting Gravatar...
this is truly one of the best ViewModel blogs that I have come across online, matey.
Cheers
Left by Shaun on Jun 28, 2012 7:41 PM

Your comment:
 (will show your gravatar)


Copyright © Brian Genisio's House Of Bilz | Powered by: GeeksWithBlogs.net