Daniel Upton
Daniel Upton

Reputation: 5751

Automatic notify property change with INotifyPropertyChanged?

I've been working on a silverlight LOB application,

In my view models i have anywhere up to 30 properties which must notify the UI when they are changed.

My ViewModel base class implements INotifyPropertyChanged and has a wrapper method called OnPropertyChanged(string propName)

This is still incredibly tedious as in all my setters i have to call this.

I'd love to be able to have it automatically be fired on certain properties / all members of a decorated class.

Is this possible?


Thanks for the solutions everyone.. I think aspect orientation may be the most concise solution for this problem.. I think this is going to usher in a great exodus away from the Silverlight/RIA/EF/MVVM norm into a much simpler more concise approach..


Oh also to make this question as useful for others as possible the AOP framework i'm going for is PostSharp and they have a tutorial on achieving just this:

http://www.sharpcrafters.com/solutions/notifypropertychanged

Upvotes: 1

Views: 1552

Answers (3)

Joe White
Joe White

Reputation: 97858

I typically end up writing my own helper method, so that my properties can have single-line getters and setters. That takes away most of the pain:

public string Name {
    get { return _name; }
    set { SetProperty(ref _name, value, () => Name); }
}
public int Value {
    get { return _value; }
    set { SetProperty(ref _value, value, () => Value); }
}

The implementation of my SetProperty method will vary depending on whether I'm using a framework like Prism or Caliburn.Micro, whether any of my viewmodels need to do extra custom work when a property changes, etc. Here's a simple implementation using Caliburn.Micro's PropertyChangedBase:

public class Observable : PropertyChangedBase
{
    protected void SetProperty<T>(ref T backingField, T newValue,
        Expression<Func<T>> property)
    {
        if (Equals(backingField, newValue))
            return;
        backingField = newValue;
        NotifyOfPropertyChange(property);
    }
}

Upvotes: 0

Valentin Kuzub
Valentin Kuzub

Reputation: 12093

Sure it is possible with AOP.

something like

[Notify]
public string PropertyName{get; set;} 

can be transformed to desired result with AOP tool

You could also apply attribute like Notify to entire viewmodel class and make each public property call NotifyPropertyChanged

There are plenty results on "AOP and NotifyPropertyChanged" in google, but I'll point at first article that I found on this topic: http://sachabarber.net/?p=849

Upvotes: 0

AnthonyWJones
AnthonyWJones

Reputation: 189555

There is no good way to reduce the amount of code needed. However the only thing that varies in each property construct is its name and its type. Hence its a good candidate for a snippet. Here is an example snippet:-

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Notify Property</Title>
      <Shortcut>np</Shortcut>
      <Description>Code snippet for a property that calls the INotifyPropertyChange event</Description>
      <Author>Coding Bloke</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>property</ID>
          <ToolTip>Property name</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>string</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private $type$ _$property$;
        public $type$ $property$
        {
            get { return _$property$; }
            set
            {
                _$property$ = value;
                OnPropertyChanged("$property$");
            }
        }
]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Save the above as

"My Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets\np.snippet"

Now you can simply type "np" in the code editor, press tab twice and this snippet will appear. Enter the type name, press tab twice, entry property name, press enter and you are done.

Upvotes: 1

Related Questions