Quickly creating ViewModel properties in wpf?

after reading this article , I have the following code in the PersonViewModel class:

 public Jurisdiction CountryResidence { get { return Model.CountryResidence; } set { if (Model.CountryResidence == value) return; else { Model.CountryResidence = value; base.OnPropertyChanged("CountryResidence"); } } } public Jurisdiction CountryBirth { get { return Model.CountryBirth; } set { if (Model.CountryBirth == value) return; else { Model.CountryBirth = value; base.OnPropertyChanged("CountryBirth"); } } } 

I also have CountryDomiciled , CountryPassport and LegalJurisdiction , all with the same format. Similarly, I have many String properties, all of which share their format.

The result is a lot of the same code! However, I cannot figure out how to make this more concise.

Is there a better way to generate these properties that allow them to strictly type?

+8
c # wpf mvvm
source share
8 answers

UPDATE: NotifyPropertyWeaver is deprecated and continues its life as PropertyChanged.Fody . This is an absolute super cool way to solve this problem. This solution is for compilation only.

Here's something that will save you code and problems: NotifyPropertyWeaver

Using the above, you can implement your properties without INotifyPropertyChanged code, and the build step will handle the wiring for you.

This is a simple project including (also accessible through Nuget) that automatically enters OnPropertyChanged into the properties of any class that implements INotifyPropertyChanged . It does this at compile time (so there is no runtime), and your code may just have automatically implemented properties (except for your case when you use a separate support object).

It even includes checking for equality of values, so it covers the full logic. I have not tested it with manually implemented properties, but worth checking out.

EDIT: I tested it now and it works great: a manually implemented property will "just work."

+4
source share

I am using snippet for Visual Studio, which generates a property with backup storage and an event for me. Just create an xml file called propchanged (or another name if you want) and the following contents:

 <?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>propchanged</Title> <Shortcut>propchanged</Shortcut> <Description>Code snippet for property (with call to OnPropertyChanged) and backing field</Description> <Author>lazyberezovsky</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>type</ID> <ToolTip>Property type</ToolTip> <Default>string</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 { if ($field$ == value) return; $field$ = value; OnPropertyChanged("$property$"); } } $end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets> 

And put it in the C:\Users\YourName\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets\ .

Then I inherit my ViewModels from some basic ViewModel that implements INotifyPropertyChanged inteface and provides a protected OnPropertyChanged method to OnPropertyChanged PropertyChanged event.

 public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName); } } 

Now when you type propchanged in Visual Studio, it asks you for the type and name of the property and generates code for you.

 public class PersonViewModel : ViewModel { // type here 'propchanged' (or other shortcut assigned for snippet) } 

UPDATE:

Another option is to generate code using an AOP framework such as PostSharp . In this case, the code will be generated and added at compile time (this way your classes will stay clean). Here is an example implementation of INotifyProperty, modified using PostSharp attributes:

 [Notify] public class PersonViewModel { public Jurisdiction CountryResidence { get; set; } public Jurisdiction CountryBirth { get; set; } } 
+8
source share

Not quite what you are looking for, but aside you can save two lines for each property by changing the logical test:

 public Jurisdiction CountryResidence { get { return Model.CountryResidence; } set { if (Model.CountryResidence != value) { Model.CountryResidence = value; base.OnPropertyChanged("CountryResidence"); } } } 
+2
source share

I don’t know any built-in way, but you can write a macro that will generate code for you. I find the easiest way to do this is to simply start recording a macro and then create everything you want using just the keyboard (you can find a list of handy keyboard shortcuts here )

For example, I have one that generates a public version of the property, so all I need to type is a private string _someValue; and click on my macro and it will generate a public property along with a property change notification.

However, keep in mind that in MVVM it is perfectly fair to expose the entire model for presentation for simplicity and convenience. Therefore, instead of exposing each of the model properties separately, you simply create one property for the Model object.

 public Model SomeModel { get { return Model; } set { if (Model == value) return; else { Model= value; base.OnPropertyChanged("SomeModel"); } } } 

And bind to model properties like this:

 <TextBox Text="{Binding SomeModel.SomeProperty}" /> 
+1
source share

Try XAML PowerToys to quickly create ViewModels;

+1
source share

To get a "strong typed" link to the property name (which is required to enable refactoring), you can use expressions. Put the following method, possibly in the base class for your view models:

 protected void RaisePropertyChanged<T>(Expression<Func<T>> property) { var handler = PropertyChanged; if (handler == null) return; var propertyName = NotifyPropertyChangedHelper.GetPropertyNameFromExpression(property); handler(sender, new PropertyChangedEventArgs(propertyName)); } 

In your view models, you can do the following:

 public Jurisdiction CountryResidence { get { return Model.CountryResidence; } set { if (Model.CountryResidence == value) return; Model.CountryResidence = value; OnPropertyChanged(() => CountryResidence); } } 

Now refactoring property names are automatically taken, since the link is against the actual property.

This solves the problem of pain in hard coding property names, although 4-5 lines of template code are still required. Aspect-oriented approaches such as notifypropertyweaver and PostSharp really remove all manual coding in view models.

+1
source share

Didn't you try to use Visual Studio code snippets like prop or propfull ? Just enter it and press the Tab key twice. The propfull snippet problem propfull not raise a PropertyChanged event.

But in fact, there must be third-party fragments for this task. Here is what I found: property fragment with INPC

0
source share
0
source share

All Articles