Using a code snippet for INotifyPropertyChanged

I found this code snippet for INotifyPropertyChanged

But it shows the code as follows:

INotifyPropertyChanged

I would have this:

  • for the public: capital letter for the first letter + ...

  • for private: underscore + small letter for the first letter + ...

How can i achieve this?

Edit: Without entering public and private fields

<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>notifyMethod</ID> <ToolTip>name of method to raise PropertyChanged event</ToolTip> <Default>NotifyPropertyChanged</Default> </Literal> </Declarations> <Code Language="csharp"> <![CDATA[private $type$ _$property$; public $type$ $property$ { get { return _$property$;} set { if (value != _$property$) { _$property$ = value; $notifyMethod$("$property$"); } } } $end$]]> </Code> </Snippet> 
+4
c # visual-studio inotifypropertychanged code-snippets
source share
5 answers

I do not think that this can be done using the built-in code snippet functions provided by Visual Studio.

Personally, I use Resharper, which makes this possible. It can turn the code that I write, for example

 public string Name { get; set; } 

in

 private string _name; public string Name { get { return _name; } set { if(value == _name) return; _name = value; OnPropertyChanged("Name"); } } 

It even generates the OnPropertyChanged() method for you.

+6
source share

fragments can be written in xml and can be made for any language in vs

 <?xml version="1.0" encoding="utf-8"?> <CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <Header> <Title>Notify Property Changed Method</Title> <Author>Akash</Author> <Shortcut>npcm</Shortcut> <Description>This method implements the OnPropertyChanged method and binds to the event handler</Description> <SnippetTypes> <SnippetType>SurroundsWith</SnippetType> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Code Language="CSharp"> <![CDATA[#region Notify Property Changed Members public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if(handler!=null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion]]> </Code> </Snippet> </CodeSnippet> 

this is the code to automatically create a method to change the notification property. all you have to do is save it in one file with the extension as a fragment in your documents / VisulaStudio (YourVersion) / code snippets / Visual C # /

that you are ready to use it ...

Now pay attention to the code fragment where there is a shortcut label. This tag refers to the tag that you must use in vs during recording to activate the fragment.

here is the code for the property itself:

 <?xml version="1.0" encoding="utf-8"?> <CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <Header> <Title>Notifiable Property</Title> <Author>Akash</Author> <Shortcut>nprop</Shortcut> <Description>Property With in Built Property Changed method implementation.</Description> <SnippetTypes> <SnippetType>SurroundsWith</SnippetType> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>Type</ID> <Default>string</Default> </Literal> <Literal> <ID>Property</ID> <Default>PlaceHolder</Default> </Literal> </Declarations> <Code Language="CSharp"> <![CDATA[private $Type$ _$Property$; public $Type$ $Property$ { get { return _$Property$; } set { if(value!=null || value != _$Property$) _$Property$ = value; OnPropertyChanged("$Property$"); } }]]> </Code> </Snippet> </CodeSnippet> 

in this particular fragment all you have to do is type nprop and click on the tab of the tab, it generates the requested code .. you only need to enter the data type and name .. the rest will be taken care of by the fragment ...

Although this is the best solution and significantly improves the coding speed, it is suitable for small projects, only the viewmodelbase method is suitable for large projects.

+11
source share

Unfortunately, this is not possible with code snippets.

You will need to convert $property$ or another literal. Even if you divide the property name into two parts (the first letter and the rest), you will need to make the letter uppercase (or vice versa - lowercase).

Fragments offer only a very limited number of conversion functions - exactly 3 for C #, and none of them can give the desired result. See Code Snippet Features on MSDN. This is true for all versions of Visual Studio prior to 2013.

+1
source share

I will give you an answer that you do not want to hear: you do not need to do this at all. Your model should have properties (full or automatic), and then your ViewModel properties should only have a receiver and setter that returns _model.MyProperty .

Alternatively, you might want to look into CallerMemberName to get rid of this annoying magic line. If you want, I will post some examples.


For example, I have a class for the DealsUser model (note how internal logic is done, for example, generating an email address if it has never been explicitly set):

 public class DealsUser : IDealsUser { public DealsUser() : this("GUEST") { } public DealsUser(string username) { this.Username = username; this.IsAdministrator = false; this.IsPlanModerator = false; this.IsPlanner = false; } public string Username { get; set; } public bool IsAdministrator { get; set; } public bool IsPlanModerator { get; set; } public bool IsPlanner { get; set; } private string _emailAddress; public string EmailAddress { get { return _emailAddress ?? string.Format( "{0}@mycompany.co.za", this.Username); } set { _emailAddress = value; } } public override string ToString() { return this.Username; } 

And I have a BaseViewModel class with the following events and protected methods (note how we use CallerMemberName to remove magic strings):

 #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { var eventHandler = this.PropertyChanged; if (eventHandler != null) { eventHandler(this, new PropertyChangedEventArgs(propertyName)); } } protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (object.Equals(storage, value)) { return false; } storage = value; this.OnPropertyChanged(propertyName); return true; } protected bool SetModelProperty<T>(T storage, T value, Action setter, [CallerMemberName] string propertyName = null) { if (object.Equals(storage, value)) { return false; } setter(); this.OnPropertyChanged(propertyName); return true; } #endregion 

Then I inherit from BaseViewModel , I am dependent, add the model to my constructor, and I try to keep my ViewModel as small as possible . Note that I should use SetModelProperty instead of SetProperty , because you cannot pass a property (e.g. _dealsUser.Username ) to the lamba function as a reference variable. Also note that IsPlanner and IsPlanModerator contain additional logic that updates the associated notification properties when they change:

 public class DealsUserVM : BaseViewModel { private readonly IDealsUser _dealsUser; public DealsUserVM() : this(new DealsUser()) { // Empty ctor } public DealsUserVM(IDealsUser dealsUser) { _dealsUser = dealsUser; } public IDealsUser Model { get { return _dealsUser; } } public string Username { get { return _dealsUser.Username; } set { SetModelProperty(_dealsUser.Username, value, () => { _dealsUser.Username = value; }); } } public bool IsAdministrator { get { return _dealsUser.IsAdministrator; } set { SetModelProperty(_dealsUser.IsAdministrator, value, () => { _dealsUser.IsAdministrator = value; }); } } public bool IsPlanModerator { get { return _dealsUser.IsPlanModerator; } set { // If IsPlanModerator has changed (and was updated as a result) if (SetModelProperty(_dealsUser.IsPlanModerator, value, () => { _dealsUser.IsPlanModerator = value; })) { // If IsPlanModerator is now TRUE if (value) { this.IsPlanner = true; } } } } public bool IsPlanner { get { return _dealsUser.IsPlanner; } set { // If IsPlanner has changed (and was updated as a result) if (SetModelProperty(_dealsUser.IsPlanner, value, () => { _dealsUser.IsPlanner = value; })) { // If IsPlanner is now FALSE if (!value) { this.IsPlanModerator = false; } } } } public string EmailAddress { get { return _dealsUser.EmailAddress; } set { SetModelProperty(_dealsUser.EmailAddress, value, () => { _dealsUser.EmailAddress = value; }); } } public override string ToString() { return _dealsUser.ToString(); } } 

Hope this helps :-)

+1
source share

Surprisingly, the following proposal has not been made. I took your original fragment (from the author’s original page) and made the following changes. You should be able to copy and paste this into your own fragment file.

 <?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>propn</Title> <Shortcut>propn</Shortcut> <Description>Code snippet for property and backing field in class implementing INotifyPropertyChanged</Description> <Author>Brian Schroer, Modified by RLH</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>type</ID> <ToolTip>Property Type</ToolTip> <Default>int</Default> </Literal> <Literal> <ID>variable</ID> <ToolTip>Underlying Variable</ToolTip> <Default>_myProperty</Default> </Literal> <Literal> <ID>property</ID> <ToolTip>Property name</ToolTip> <Default>MyProperty</Default> </Literal> <Literal> <ID>notifyMethod</ID> <ToolTip>name of method to raise PropertyChanged event</ToolTip> <Default>NotifyPropertyChanged</Default> </Literal> </Declarations> <Code Language="csharp"><![CDATA[private $type$ $variable$; public $type$ $property$ { get { return $variable$;} set { if (value != $variable$) { $variable$ = value; PropertyChanged(this, new PropertyChangedEventArgs("$property$")); } } } $end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets> 

What changed

First I added a new variable literal. This creates a new, updatable element that you can insert from the fragment. By default, the variable name is _propertyName , which, as you can see, is a lowercase name. Note that unlike the original fragment, the underscore was hard-coded before the PropertyName literal. In my code, I separated the variable name from the property name.

I decided not to hardcode the underscore in my fragment so that if others use this code, they can choose a different style for the variable name. However, by default, I hint at using underscores.

If you want to force the underscore, change the default value of variable to PropertyName . Then, everywhere variable refers, place the _ symbol in front of the link.

0
source share

All Articles