Some helpful MVVM snippets

If you’re doing any significant amount of MVVM / XAML work, then I hope you’ll find these Visual Studio snippets useful.

This first snippet creates a backing field, a property with a simple getter, and a setter that also calls RaiseNotifyPropertyChanged. This would usually be created in a ViewModel.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets mlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>MVVM Property</Title>
      <Author>Phil Chuang</Author>
      <Description>A snippet for generating a backed Property that calls RaisePropertyChanged</Description>
      <HelpUrl></HelpUrl>
      <Shortcut>mvvmprop</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>Type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>Object</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>PropertyName</ID>
          <ToolTip>Property name</ToolTip>
          <Default>Property</Default>
          <Function>
          </Function>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[private $Type$ my$PropertyName$;
public $Type$ $PropertyName$
{
  get { return my$PropertyName$; }
	set
	{
		my$PropertyName$ = value;
		RaisePropertyChanged (() => $PropertyName$);
	}
}]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

This snippet also has a shortcut. So you can be typing along in your ViewModel class, and you can quickly add a property by

  1. typing mvvmprop, and hitting tab
  2. typing the Type of the property, such as String, and hitting tab
  3. typing the name of the property, such as FirstName, and hitting tab

This creates the following code:

private String myFirstName;
public String FirstName
{
	get { return myFirstName; }
	set
	{
		myFirstName = value;
		RaisePropertyChanged (() => FirstName);
	}
}

(Don’t worry about RaisePropertyChanged (() => $PropertyName$), that’ll get explained later)

The next snippet creates a static DependencyProperty and related instance property, which would usually go on a UserControl.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets mlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>MVVM Dependency Property</Title>
      <Author>Phil Chuang</Author>
      <Description>A snippet for generating a Dependency Property</Description>
      <HelpUrl></HelpUrl>
      <Shortcut>mvvmdepprop</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>PropertyType</ID>
          <ToolTip>Property type</ToolTip>
          <Default>Object</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>PropertyName</ID>
          <ToolTip>Property name</ToolTip>
          <Default>Property</Default>
          <Function>
          </Function>
        </Literal>
        <Literal default="true" Editable="false">
          <ID>ClassName</ID>
          <ToolTip>Class name</ToolTip>
          <Function>ClassName()</Function>
          <Default>ClassNamePlaceholder</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[public $PropertyType$ $PropertyName$
		{
			get { return ($PropertyType$) GetValue ($PropertyName$Property); }
			set { SetValue ($PropertyName$Property, value); }
		}

		public static readonly DependencyProperty $PropertyName$Property = DependencyProperty.Register (
			INotifyPropertyChangedHelper.GetPropertyName (($ClassName$ c) => c.$PropertyName$),
			typeof ($PropertyType$),
			typeof ($ClassName$),
			new PropertyMetadata (null, On$PropertyName$Changed));

		private static void On$PropertyName$Changed (DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			var instance = d as $ClassName$;

			if (instance == null) return;
      
      var oldValue = ($PropertyType$) e.OldValue;
      var newValue = ($PropertyType$) e.NewValue;

			// TODO implement
		}]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

The shortcut for this snippet is mvvmdepprop, and it’ll behave exactly the same as the first snippet.

And last but not least, I’ve included a static class with helper methods for determining a property name via reflection at runtime. This is great because you won’t have to worry about magic strings any more, any change to a property name will get noticed at compile-time.

public static class INotifyPropertyChangedHelper
{
	public static String GetPropertyName<T> (Expression<Func<T>> propertyExpression)
	{
		if (propertyExpression == null) throw new ArgumentNullException ("propertyExpression");

		if (propertyExpression.Body.NodeType == ExpressionType.MemberAccess)
		{
			var memberExpr = (MemberExpression) propertyExpression.Body;
			return memberExpr.Member.Name;
		}

		if (propertyExpression.Body.NodeType == ExpressionType.Convert
			&& propertyExpression.Body is UnaryExpression
			&& ((UnaryExpression) propertyExpression.Body).Operand.NodeType == ExpressionType.MemberAccess)
		{
			var memberExpr = (MemberExpression) ((UnaryExpression) propertyExpression.Body).Operand;
			return memberExpr.Member.Name;
		}

		throw new Exception (String.Format ("Expected MemberAccess expression, got {0}", propertyExpression.Body.NodeType));
	}

	public static String GetPropertyName<T, V> (Expression<Func<T, V>> propertyExpression)
	{
		if (propertyExpression == null) throw new ArgumentNullException ("propertyExpression");

		if (propertyExpression.Body.NodeType == ExpressionType.MemberAccess)
		{
			var memberExpr = (MemberExpression) propertyExpression.Body;
			return memberExpr.Member.Name;
		}

		if (propertyExpression.Body.NodeType == ExpressionType.Convert
			&& propertyExpression.Body is UnaryExpression
			&& ((UnaryExpression) propertyExpression.Body).Operand.NodeType == ExpressionType.MemberAccess)
		{
			var memberExpr = (MemberExpression) ((UnaryExpression) propertyExpression.Body).Operand;
			return memberExpr.Member.Name;
		}

		throw new Exception (String.Format ("Expected MemberAccess expression, got {0}", propertyExpression.Body.NodeType));
	}
}

All 3 files can be found at this https://gist.github.com/philchuang/6168400.

Leave a Reply