PlTaylor
PlTaylor

Reputation: 7525

How to automate the creation of WPF Viewmodel properties

I am using Visual Studio '17 and Resharper in a WPF project that displays a lot of information to the user. Therefore I have a lot of properties that look like the following.

private double _foo;
public double Foo
{
   get { return _foo; }
   set { SetProperty(ref _foo, value); }
}

I'm looking for a quick automated way to create this. Right now I type 'prop' and get this

public double Foo {get; set;}

hit 'Alt-Enter' -> 'To property with backing field' to get this

private double _foo;
public double Foo
{
   get { return _foo; }
   set { _foo = value); }
}

and then manually type in the SetProperty(ref and ',' to get the final result. I've tried setting up snippets and resharper Templates but can't seem to figure out how to do it in one operation. What have people come up with to make this easier? Specifically, it would help tremendously if I could change an already existing auto-property to a View Model property.

Upvotes: 4

Views: 1243

Answers (4)

Sergey Vlasov
Sergey Vlasov

Reputation: 27930

With my Visual Commander extension, you can use the following C# command (References: Microsoft.VisualBasic) to create a view model property:

public class C : VisualCommanderExt.ICommand
{
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        string propertyName = Microsoft.VisualBasic.Interaction.InputBox("Property name", "Create view model property [1/2]", "Foo", -1, -1);
        string propertyType = Microsoft.VisualBasic.Interaction.InputBox("Property type", "Create view model property [2/2]", "double", -1, -1);
        string fieldName = "_" + System.Char.ToLower(propertyName[0]) + propertyName.Substring(1);
        string snippet = @"
private {1} {2};
public {1} {0}
{{
   get {{ return {2}; }}
   set {{ SetProperty(ref {2}, value); }}
}}
";
        EnvDTE.TextSelection ts = DTE.ActiveDocument.Selection as EnvDTE.TextSelection;
        ts.Text = string.Format(snippet, propertyName, propertyType, fieldName);
    }
}

With C# 6 it is simpler, but requires Visual Commander Professional:

public class C : VisualCommanderExt.ICommand
{
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        string propertyName = Microsoft.VisualBasic.Interaction.InputBox("Property name", "Create view model property [1/2]", "Foo", -1, -1);
        string propertyType = Microsoft.VisualBasic.Interaction.InputBox("Property type", "Create view model property [2/2]", "double", -1, -1);
        string fieldName = "_" + System.Char.ToLower(propertyName[0]) + propertyName.Substring(1);

        EnvDTE.TextSelection ts = DTE.ActiveDocument.Selection as EnvDTE.TextSelection;
        ts.Text = $@"
private {propertyType} {fieldName};
public {propertyType} {propertyName}
{{
   get {{ return {fieldName}; }}
   set {{ SetProperty(ref {fieldName}, value); }}
}}
";
    }
}

Upvotes: 0

ivica.moke
ivica.moke

Reputation: 1064

U can create your own snippet for that. I've create propbb snippet for BindableBase(from PRISM) property, it's essentialy same as you want. To create snippet here is video i've followed.

https://www.youtube.com/watch?v=tGmXlUFMTpk

and my snippet looks like this

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>propbb</Title>
      <Shortcut>propbb</Shortcut>
      <Description>Code snippet for BindableBase property and backing field</Description>
      <Author></Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>int</Default>
        </Literal>
        <Literal>
          <ID>property</ID>
          <ToolTip>Property name</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>field</ID>
          <ToolTip>The variable backing this property</ToolTip>
          <Default>myVar</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private $type$ $field$;
                   public $type$ $property$
                  {
                    get { return $field$;}
                      set { SetProperty(ref $field$ , value);}
                  }
    $end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

if you want this is my snippet, just include it in your visual studio(like in video i've provided)

propbb snippet download

Path to add snippet in VS2017: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC#\Snippets\1033\Visual C# Just download snippet from my dropbox and copy there, to use it write propbb and tab tab

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70701

You can define your own code snippet, to suit your needs precisely.

Here's one I wrote for myself, to generate property implementations compatible with the INotifyPropertyChanged base class implementation I also use regularly:

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>INPCProperty</Title>
      <Author>Peter Duniho</Author>
      <Description>Property declaration for NotifyPropertyChangedBase</Description>
      <Shortcut>inpcprop</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>fieldName</ID>
          <Default>_fieldName</Default>
          <ToolTip>Enter actual field name here</ToolTip>
        </Literal>
        <Literal>
          <ID>fieldType</ID>
          <Default>object</Default>
          <ToolTip>Enter actual field value type here</ToolTip>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[private $fieldType$ $fieldName$;
        public $fieldType$ FieldName
        {
            get { return $fieldName$; }
            set { _UpdateField(ref $fieldName$, value); }
        }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Use the Visual Studio Snippet Manager to add the snippet to your installation.

(I didn't bother adding a field for the property name itself, because there didn't seem any point to it. But you can, of course, if you like. The only advantage I see vs. just selecting the property name and over-typing it is that if it's a field, you should be able to use the tab key to get directly to it before over-typing.)

Upvotes: 2

user5420778
user5420778

Reputation:

Install the Prism Template Pack from the Visual Studio Marketplace and then use the "propp" snippet.

https://marketplace.visualstudio.com/items?itemName=BrianLagunas.PrismTemplatePack

Upvotes: 0

Related Questions