[PL] implementacja interfejsu INotifyPropertyChanged poprzez refleksję
Korzystanie z interfejsu INotifyPropertyChanged podczas pracy z WPF to praktycznie codzienność. Za którymś razem jednak implementacja tego interfejsu w kolejnej klasie może już zbrzydnąć. Dlaczego, więc nie skorzystać z refleksji i extensions methods? Metodę wywołującą zdarzenie PropertyChanged napiszemy raz i będziemy z niej korzystać do woli. Implementacja tej metody w moim wykonaniu wygląda następująco:
public static class INotifyPropertyChangedExtension { public static void OnPropertyChanged(this INotifyPropertyChanged sender, string propertyName) { Type type = sender.GetType(); while (type != null) { FieldInfo eventFieldInfo = type.GetField("PropertyChanged", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance); if (eventFieldInfo != null) { MulticastDelegate eventDelegate = eventFieldInfo.GetValue(sender) as MulticastDelegate; if (eventDelegate != null) { eventDelegate.DynamicInvoke(new object[] { sender, new PropertyChangedEventArgs(propertyName) }); break; } } type = type.BaseType; } } }
Najważniejsza w tym przypadku jest pętla. Dzięki niej będziemy w stanie wywołać zdarzenie PropertyChanged z klas potomnych. Taka sytuacja w projekcie DotBeer ma miejsce np. w klasie OptionsWindowViewModel, która dziedziczy po klasie bazowej ViewModelBase.
Strasznie to brzydkie:
1. ze względu na refleksję
2. ze względu na propertyName (a można przecież użyć Lambda Expressions)
Polecam posty:
http://blog.decarufel.net/2010/03/how-to-use-strongly-typed-name-with.html
http://www.clariusconsulting.net/blogs/kzu/archive/2010/05/14/244098.aspx