Posts Tagged ‘MVVM’

INotifyPropertyChanged with lambdas

Tuesday, February 16th, 2010

There are several ways of implementing INotifyPropertyChanged in WPF applications.

One that I particularly like is by using PostSharp to implement INotifyPropertyChanged.

If you are not comfortable with PostSharp you can at least get rid of those nasty strings in standard implementation:

public class Model : ViewModeBase
{
    private string _status;
    public string Status
    {
        get { return _status; }
        set
        {
            _status = value;
            OnPropertyChanged("Status");
        }
    }
};

Labda expressions look nicer and are easier to refactor:

public class MyModel : ViewModeBase
{
    private string _status;
    public string Status
    {
        get { return _status; }
        set
        {
            _status = value;
            OnPropertyChanged(() => Status);
        }
    }
};

First thing we need to do is to create base class for all our ViewModels:

public class ViewModelBase
{
    public event PropertyChangedEventHandler PropertyChanged
        = delegate { };

    protected void OnPropertyChanged(
        Expression<func<object>> expression)
    {
        string propertyName = PropertyName.For(expression);
        this.PropertyChanged(
            this,
            new PropertyChangedEventArgs(propertyName));
    }
};

The implementation of PropertyName.For is very straightforward: How to get property name from lambda.

That’s it!
Nice, easy to refactor, compile-time checked INotifyPropertyChanged implementation.

M-V-VM talk

Tuesday, October 13th, 2009

thumbnail
Here are the slide-show and code from my recent M-V-VM talk on the Warsaw .NET group. I was talking about different flavors of MVVM, blendability, unit testing and separation of concerns. All in all, I think it was a good talk with great audience participation.

MVVM_Presentation
MyMVVMSample

INotifyPropertyChanged with PostSharp 1.5

Tuesday, September 15th, 2009

If you are doing WPF development, most likely you are tired of writing property implementations that raise PropertyChanged event manually:

public class MainWindowViewModel : ViewModel
{
    private string _message;

    public string Message
    {
        get
        {
            return _message;
        }
        set
        {
            _message = value;
            OnPropertyChanged("Message");
        }
    }

    // ...
}

PostSharp is a great tool to make such things simplier.

Let’s look at the specific ViewModel class that has a Message property that is bound to some UI element using XAML:

public class MainWindowViewModel : ViewModel
{
    [RaisePropertyChanged]
    public string Message { get; set; }

    // ...
}

Notice the RaisePropertyChanged attribute, which we’ll implement later.

Here’s our base ViewModel class that provides actual implementation of the INotifyPropertyChanged interface:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged
        = delegate { };

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
    }
};

Finally the PostSharp attribute:

[Serializable]  // required by PostSharp
public class RaisePropertyChangedAttribute : OnMethodBoundaryAspect
{
    private string _propertyName;

    /// <summary>
    /// Executed at runtime, after the method.
    /// </summary>
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        ViewModel viewModel = (ViewModel)eventArgs.Instance;
        viewModel.OnPropertyChanged(_propertyName);
    }

    public override bool CompileTimeValidate(MethodBase method)
    {
        if (IsPropertySetter(method))
        {
            _propertyName = GetPropertyName(method);
            return true;
        }
        return false;
    }

    private static string GetPropertyName(MethodBase method)
    {
        return method.Name.Replace"set_", "");
    }

    private static bool IsPropertySetter(MethodBase method)
    {
        return method.Name.StartsWith("set_");
    }
};

Note that we are validating if the method is in fact a property only during compilation time using CompileTimeValidate method.

During compile time appropriate invocations of OnPropertyChanged method will be injected after every set operation applied to the Message property.