/// <summary> /// Returns the specified args as <see cref="PropertyMutatedEventArgs{T}"/>. /// </summary> public static PropertyMutatedEventArgs <T> OfType <T>(this IPropertyMutatedEventArgs args) { Contract.Requires(args != null); return((args as PropertyMutatedEventArgs <T>) ?? new PropertyMutatedEventArgs <T>(args.PropertyName, (T)args.OldValue, (T)args.NewValue)); }
/// <summary> Invokes the specified handler when a collection property on a property changes, when the source changes, /// or when the collection changes. </summary> /// <param name="propertyName"> The name of the property on the source. </param> /// <param name="collectionPropertyOnPropertyName"> The name of the collection property on the property on the source, i.e. <code>source.property.collectionProperty</code></param> /// <param name="handler"> The handler to be invoked at the moments listed above. </param> public static void BindCollection(this INotifyPropertyChanged source, string propertyName, string collectionPropertyOnPropertyName, NotifyCollectionChangedEventHandler handler) { Contract.Requires(GetPropertyType(source.GetType(), propertyName, collectionPropertyOnPropertyName).Implements(typeof(INotifyCollectionChanged)), $"The collection property '{collectionPropertyOnPropertyName}' on the source must implement '{nameof(INotifyCollectionChanged)}'"); source.Bind(propertyName, collectionPropertyOnPropertyName, RebindCollectionChangedHandler); void RebindCollectionChangedHandler(object sender, PropertyChangedEventArgs eventArg) { IPropertyMutatedEventArgs e = (IPropertyMutatedEventArgs)eventArg; Contract.Requires(sender != null); Contract.Requires(e != null); Contract.Requires(e.OldValue == null || e.OldValue.GetType().Implements(typeof(INotifyCollectionChanged)), "The collection instance must implement 'INotifyCollectionChanged'"); Contract.Requires(e.NewValue == null || e.NewValue.GetType().Implements(typeof(INotifyCollectionChanged)), "The collection instance must implement 'INotifyCollectionChanged'"); Contract.Requires(e.OldValue == null || e.OldValue.GetType().Implements(typeof(System.Collections.IList)), "The collection instance must implement 'IList'"); Contract.Requires(e.NewValue == null || e.NewValue.GetType().Implements(typeof(System.Collections.IList)), "The collection instance must implement 'IList'"); if (e.OldValue is INotifyCollectionChanged oldCollection) { oldCollection.CollectionChanged -= handler; } if (e.NewValue is INotifyCollectionChanged newCollection) { newCollection.CollectionChanged += handler; handler(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newCollection, e.OldValue as System.Collections.IList)); } } }