PropertyChanged – Komplett und kompakt!

Wer kennt es nicht, immer wieder das Ableiten von „INotifyPropertyChanged“ und das nervige Implementieren dieser Funktionalität. Auch wenn inzwischen der neue ReSharper in der Lage ist, diese Methode automatisiert komplett zu Implementieren, so ist dies bei weitem noch nicht beim maximalen Komfort. Aber natürlich gibt es hierfür einige Nützliche Wege dies zu umgehen. Ich würde hierfür eine eigene Klasse empfehlen von welcher in Zukunft Abgeleitet werden kann. Natürlich setzt dies auch wiederum etwas voraus und zwar ist dies bei meiner Umsetzung das mindestens .NET Framework 2.0 verwendet wird. Ist dies der Fall kann diese Klasse bedenkenlos Verwendet werden da diese explizit die .NET Version filtert. Den maximalen Komfort bietet diese Klasse jedoch erst mithilfe von .NET 4.5 bei welchen nicht einmal mehr ein Übergabe Parameter notwendig ist. 

public abstract class PropertyChangedBase : INotifyPropertyChanged
{
    protected SynchronizationContext uiContext = SynchronizationContext.Current;

    public event PropertyChangedEventHandler PropertyChanged;

    #if NET45

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (uiContext != null)
        {
            uiContext.Send(delegate
                {
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }, null);
        }
        else
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #else

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (uiContext != null)
        {
            uiContext.Send(delegate
                {
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }, null);
        }
        else
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endif

    protected virtual void MultipleOnPropertyChanged(string[] propertys)
    {
        foreach (string property in propertys)
            OnPropertyChanged(property);
    }

    #if !NET20 && !NET30

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> expression)
    {
        OnPropertyChanged(GetPropertyName(expression));
    }

    protected virtual void MultipleOnPropertyChanged<T>(Expression<Func<T>>[] expressions)
    {
        foreach (Expression<Func<T>> expression in expressions)
            OnPropertyChanged(GetPropertyName(expression));
    }

    protected string GetPropertyName<T>(Expression<Func<T>> expression)
    {
        MemberExpression memberExpression = expression.Body as MemberExpression;
        return memberExpression != null ? memberExpression.Member.Name : "";
    }

    #endif
}

Nun ist natürlich noch die Frage, wie diese Klasse verwendet werden kann. Aber dies ist sehr einfach. So kann das „OnPropertyChanged“ mit verschiedenen Parametern genutzt werden, zum einen natürlich ein string welcher den Namen der Eigenschaft beinhaltet aber auch zum anderen mittels Expressions, welche auf der Eigenschaft zeigen. Ein Beispiel hierfür wäre folgendes:

private string _someProperty;
public string SomeProperty
{
    get { return _someProperty; }
    set
    {
        _someProperty = value;
        OnPropertyChanged(() => SomeProperty);
    }
}

Wie bereits erwähnt, ist dies aber alles unter .NET 4.5 nicht mehr nötig da die Methode „OnPropertyChanged“ Parameterlos Aufgerufen werden kann und Ihren Job erledigt. Die nötige Klasse kann hier heruntergeladen werden, Kommentare und Anregungen sind erwünscht. 🙂