[PL] implementacja interfejsu INotifyPropertyChanged poprzez refleksję

Promuj

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.