Shiraz Bhaiji Shiraz Bhaiji - 1 year ago 91
C# Question

Better way to trigger OnPropertyChanged

We have a WPF Project that follows the MVVM pattern.

In the View Model there is a lot of code that looks like this:

private string m_Fieldname;
public string Fieldname
get { return m_Fieldname; }
m_Fieldname = value;

Is there a way to do this that would require less code?

Would be nice with something like this:

public string Fieldname { get; set ; }

Answer Source

You could have a look at PostSharp. They even have a sample at Data Binding. The code taken from there:

/// <summary>
/// Aspect that, when apply on a class, fully implements the interface 
/// <see cref="INotifyPropertyChanged"/> into that class, and overrides all properties to
/// that they raise the event <see cref="INotifyPropertyChanged.PropertyChanged"/>.
/// </summary>
[IntroduceInterface( typeof(INotifyPropertyChanged), 
                     OverrideAction = InterfaceOverrideAction.Ignore )]
[MulticastAttributeUsage( MulticastTargets.Class, 
                          Inheritance = MulticastInheritance.Strict )]
public sealed class NotifyPropertyChangedAttribute : InstanceLevelAspect, 

    /// <summary>
    /// Field bound at runtime to a delegate of the method <c>OnPropertyChanged</c>.
    /// </summary>
    [ImportMember( "OnPropertyChanged", IsRequired = false)] 
    public Action<string> OnPropertyChangedMethod;

    /// <summary>
    /// Method introduced in the target type (unless it is already present);
    /// raises the <see cref="PropertyChanged"/> event.
    /// </summary>
    /// <param name="propertyName">Name of the property.</param>
    [IntroduceMember( Visibility = Visibility.Family, IsVirtual = true, 
                      OverrideAction = MemberOverrideAction.Ignore )]
    public void OnPropertyChanged( string propertyName )
        if ( this.PropertyChanged != null )
           this.PropertyChanged( this.Instance, 
                                  new PropertyChangedEventArgs( propertyName ) );

    /// <summary>
    /// Event introduced in the target type (unless it is already present);
    /// raised whenever a property has changed.
    /// </summary>
    [IntroduceMember( OverrideAction = MemberOverrideAction.Ignore )]
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Method intercepting any call to a property setter.
    /// </summary>
    /// <param name="args">Aspect arguments.</param>
     MulticastPointcut( Targets = MulticastTargets.Property, 
         Attributes = MulticastAttributes.Instance)]
    public void OnPropertySet( LocationInterceptionArgs args )
        // Don't go further if the new value is equal to the old one.
        // (Possibly use object.Equals here).
        if ( args.Value == args.GetCurrentValue() ) return;

        // Actually sets the value.

        // Invoke method OnPropertyChanged (our, the base one, or the overridden one).
        this.OnPropertyChangedMethod.Invoke( args.Location.Name );


Usage is then as simple as this:

public class Shape
   public double X { get; set; }
   public double Y { get; set; }

Examples taken from PostSharp site and inserted for completing the answer