A while a go, I had a post regarding how to implement the INotifyPropertyChanged event in a more proper fashion. You didn’t have to hard-code the property name, and could instead use a linq expression, which with a help of an extension method, the name of the property is easily extracted, and passed to raise the PropertyChanged event. Simple, right?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static class EventExtension
{
public static void Notify<T, TValue>(this T instance, PropertyChangedEventHandler handler, Expression<Func<T, TValue>> selector) where T : INotifyPropertyChanged
{
if (handler != null)
{
var memberExpression = selector.Body as MemberExpression;
if (memberExpression == null)
throw new InvalidOperationException(“selector should be a MemberExpression.”);

handler(instance, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
}

public abstract class NotificationAwareBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}

public class Customer : NotificationAwareBase
{
private string _Name;

public string Name
{
get { return _Name; }
set
{
_Name = value;
this.Notify(base.PropertyChanged, o => o.Name);
}
}
}

Should work like a charm, right? WRONG! you’ll end up with a compile time error. It is like the extension method does not like my inherited PropertyChanged event. The drawback to the latter method was that you could not use it in inheritance context.

I need to implement INotifyPropertyChanged only once (Layer Supertype, anyone?). I had to come up with something to be able to work in inheritance context. Finally, here’s it :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public abstract class NotificationAware : INotifyPropertyChanged
{
private event PropertyChangedEventHandler propertyChangedEvent;

public event PropertyChangedEventHandler PropertyChanged
{
add
{
propertyChangedEvent += value;
}
remove
{
propertyChangedEvent -= value;
}
}

protected void Notify<T>(T obj, Expression<Func<T, object>> selector)
{
if (propertyChangedEvent != null)
{
MemberExpression memberExpression = selector.Body as MemberExpression;
if (memberExpression == null)
{
UnaryExpression unary = selector.Body as UnaryExpression;
if (unary != null)
{
memberExpression = unary.Operand as MemberExpression;
}
}

if(memberExpression == null)
throw new ArgumentException("member should be of MemberExpression type", "selector");


propertyChangedEvent(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
}

public class Customer : NotificationAware
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
Notify(this, o => o.Name);
}
}
}

Happy coding!