views:

703

answers:

6

Is there a concise way to define properties in a ViewModel for data binding in C# WPF? The following property definition is very verbose, especially when there are lots of properties:

private bool mSomeProperty;

public bool SomeProperty
{
    get { return this.mSomeProperty; }
    set
    {
        if (value != this.mSomeProperty)
        {
            this.mSomeProperty = value;
            OnPropertyChanged(new PropertyChangedEventArgs("SomeProperty"));
        }
    }
}
A: 

If you're using the Delphi Prism language (Pascal-based .NET language), you just add the notify keyword, and the compiler automatically implements INotifyPropertyChanged and writes all the boilerplate code for you:

property SomeProperty: bool; notify;
Joe White
A: 

I think you won't get the property declaration much smaller than that, at least not with "normal" ways. You could use an castle interceptor to take care of the event raisal.

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChanged;
    public void FirePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(propertyName);
    }

    public virtual string MyProperty { get; set; }
    public virtual string MyProperty2 { get; set; }
}

The interceptor would need to fire the property changed event:

public class PropertyChangedInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        //Pseudo code
        if (invocation.Method is Property Setter)
        {
            Call FirePropertyChanged of invocation.InvocationTarget ;
        }
    }
}

You just need to make sure that your view model's properties are virtual and your view model is always an proxy and not the view model itself.

Best Regards

Oliver Hanappi
+2  A: 

In C#, I like to make a base class and put some helper methods on it. Then I make my ViewModels descend from it. This is from memory, but it's something like this:

public class Observable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void SetProperty<T>(ref T backingField, T newValue,
        string propertyName)
    {
        if (Equals(backingField, newValue))
            return;
        backingField = newValue;
        if (PropertyChanged != null)
        {
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }
}

And, in usage:

public class MyClass : Observable
{
    private bool m_someProperty;

    public bool SomeProperty
    {
        get { return m_someProperty; }
        set { SetProperty(ref m_someProperty, value, "SomeProperty"); }
    }
}
Joe White
This is actually identical to one solution I've already implemented, but it still feels clunky to me. It is a step in the right direction though.
emddudley
@emddudley - actually, his method of implementing INotifyPropertyChanged in the base class is a very important improvement over the code in your question. If you use your code, and try to make a derived class, you can't raise the event of the base class from the derived class. You pretty much have to make a NotifyPropertyChanged() method in your base class to make this work.
Scott Whitlock
+1  A: 

You could always use DependencyProperties and propdp your heart out...

Will
I won't use DependencyProperties in a ViewModel. See http://stackoverflow.com/questions/291518/inotifypropertychanged-vs-dependencyproperty-in-viewmodel for more information.
jbe
Its really up to you. The post you linked to doesn't give any good reasons for not using DP's other than they are more heavy weight than POCOs. Unless you actually are experiencing issues using them prematurely optimizing them out of the equation is... premature optimization. A project I'm working on right now has ~40 VM's and M's, all of which extend DP, and I haven't noticed the application running slowly.
Will
A: 

You can consider PostSharp which will allow you to decorate the property (which you could then redefine as an auto property) and inject into the setter the line that fires the NotifyPropertyChanged event. An added benefit is you get rid of the string that is the same as the property name.

It's not ideal because you need that tool and it won't be immediately obvious if you are looking at the code later, but it definitely makes it neater.

I was hoping MSFT would add such an attribute to C# 4 but I guess we'll have to wait for C#5 if at all.

Gus Paul
+1  A: 

You might find some ideas here:

Best Practices: How to implement INotifyPropertyChanged right? http://compositeextensions.codeplex.com/Thread/View.aspx?ThreadId=53731

jbe