making resharper and mvvm light’s viewmodelbase play nice

ReSharper and MVVM Light are probably my two most used pieces of software. I can’t live without Resharper’s refactoring skills and doing any kind of XAML development without using MVVM Light is just crazy (my opinion of course Glimlach).

One of the more annoying things in XAML based software is the need to write full properties that call the PropertyChanged event in the setter. If your project is data intensive you’ll probably need a lot of those properties, luckily Resharper can help us there.

The Resharper solution

When you make your class implement INotifyPropertyChanged it requires you to implement its members, Resharper comes with a built-in implementation, just press alt-enter and behold.

After inserting the code Resharper asks if you want to include some annotations in your project, and these annotations make some magic happen, so I would strongly advice to add them.

Once you click Yes you’ll notice that a new class is added to your project under the Properties folder. The INotifyPropertyChanged implementation looks like this

Code Snippet
  1. public class MyBase : INotifyPropertyChanged
  2. {
  3.     public event PropertyChangedEventHandler PropertyChanged;
  5.     [NotifyPropertyChangedInvocator]
  6.     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  7.     {
  8.         PropertyChangedEventHandler handler = PropertyChanged;
  9.         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
  10.     }
  11. }

As you can see Resharpes uses the CallerMemberName attribute new in .net 4.5, this way we won’t have to specify the property’s name anymore when we call OnPropertyChanged. Line 5 is what will make the next piece of Resharper magic happen.

Now we want to add some properties to the class and make them call OnPropertyChanged in the setter. I start of with an autoproperty

Code Snippet
  1. public string Name { get; set; }

Next I alt-enter the property. Resharper now checks the class and its baseclasses if available, if one of those has the NotifyPropertyChangedInvocator attribute it will show an extra option in the menu.

Selecting that option will turn the autoproperty into

Code Snippet
  1. private string _name;
  2. public string Name
  3. {
  4.     get { return _name; }
  5.     set
  6.     {
  7.         if (value == _name) return;
  8.         _name = value;
  9.         OnPropertyChanged();
  10.     }
  11. }

Mission accomplished, we create a bunch of autoproperties, alt-enter them and save a lot of time.

The MVVM Light problem

The MVVM Light viewmodels all inherit from ViewModelBase, ViewModelBase inherits from ObservableObject and ObservableObject implements INotifyPropertyChanged

Code Snippet
  1. public abstract class ViewModelBase : ObservableObject, ICleanup


Code Snippet
  1. public class ObservableObject : INotifyPropertyChanged

And here’s the MVVM Light implementation of INotifyPropertyChanged

Code Snippet
  1. public event PropertyChangedEventHandler PropertyChanged;
  3. protected virtual void RaisePropertyChanged(string propertyName)
  4. {
  5.     VerifyPropertyName(propertyName);
  7.     var handler = PropertyChanged;
  8.     if (handler != null)
  9.     {
  10.         handler(this, new PropertyChangedEventArgs(propertyName));
  11.     }
  12. }
  14. public void VerifyPropertyName(string propertyName)
  15. {
  16.     var myType = GetType();
  18.     if (!string.IsNullOrEmpty(propertyName)
  19.         && myType.GetProperty(propertyName) == null)
  20.     {
  21.         throw new ArgumentException("Property not found", propertyName);
  22.     }
  23. }

A nice implementation but it lacks the attributes required for Resharper to implement a backing field with change notification. Meaning that we still have to write the implementation ourselves or we need to build our own ViewModelBase and implement INotifyPropertyChanged our self, which is a bit of a shame since this nice implementation already exists.

A solution

The solution I came up with does require us to build a viewmodelbase, but to be honest I tend to do that in almost every project, for example for an IsDataLoading bindable property, that’s useful in every page. The ViewModel base class that we’ll build inherits from ViewModelBase and overrides the RaisePropertyChanged. Do make sure that the annotations.cs class from Resharper is present in your project.

Code Snippet
  1. public class MyBase : ViewModelBase
  2. {
  3.      /// <summary>
  4.     /// This gives us the ReSharper option to transform an autoproperty into a property with change notification
  5.     /// Also leverages .net 4.5 callermembername attribute
  6.     /// </summary>
  7.     /// <param name="property">name of the property</param>
  8.     [NotifyPropertyChangedInvocator]
  10.     protected override void RaisePropertyChanged([CallerMemberName]string property = "")
  11.     {
  12.         base.RaisePropertyChanged(property);
  13.     }
  14. }

The overriden method just calls its base method and passes in the parameter. But thanks to .net 4.5 and the attribute we can now use the CallerMemberName attribute and Resharper’s alt-enter magic in MVVM Light while still having the ViewModelBase.

<p>And the result of that action is like you would suspect</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:da3cac00-a96c-4e75-bd5c-0e43d9f330bc" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> _name;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> Name</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _name; }</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">set</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000"> == _name) </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">_name = </span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">;</span></li> <li>        <span style="background:#ffffff;color:#000000">RaisePropertyChanged();</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <h2>Conclusion</h2>  <p>In this post I’ve shown a quick fix I use to make two of my favorite bits play together nicely without changing any of the native implementations, I still use the ViewModelBase way of notifying when a property changed and I can make use of Resharper to quickly write those properties.</p>

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.


Leave a Comment