/// <summary> /// Replaces a wrapped reference list, detaching contained items if needed, and confiures the wrapper to wrap a /// replacement list. /// </summary> /// <param name='wrapperToOverwrite'> /// The wrapper instance to overwrite. /// </param> /// <param name='replacement'> /// The replacement source list. /// </param> /// <param name='referenceProperty'> /// An expression indicating a property upon the contained type. /// </param> /// <param name='referenceItem'> /// The reference item to be stored in the <paramref name="referenceProperty"/>. /// </param> /// <typeparam name='T'> /// The type of item contained within the list. /// </typeparam> /// <remarks> /// <para> /// See the documentation of this type for detailled information on how this works and what it does. /// </para> /// </remarks> public static void Replace <T>(ref ICollection <T> wrapperToOverwrite, ICollection <T> replacement, Expression <Func <T, object> > referenceProperty, object referenceItem) where T : class { if (replacement == null) { throw new ArgumentNullException("replacement"); } EventBoundCollectionWrapper <T> typedList = wrapperToOverwrite as EventBoundCollectionWrapper <T>; if (typedList != null) { typedList.DetachAll(); } PropertyInfo propInfo = Reflect.Property(referenceProperty); foreach (T item in replacement) { propInfo.SetValue(item, referenceItem, null); } wrapperToOverwrite = GetOrInit(replacement, referenceProperty, referenceItem); }
/// <summary> /// Gets a wrapped reference list, initialising it if required. /// </summary> /// <returns> /// A generic ICollection, with added addition and removal handlers. /// </returns> /// <param name='wrapper'> /// The list wrapper instance to use. /// </param> /// <param name='original'> /// The original/source list. /// </param> /// <param name='referenceProperty'> /// An expression indicating a property upon the contained type. /// </param> /// <param name='referenceItem'> /// The reference item to be stored in the <paramref name="referenceProperty"/>. /// </param> /// <typeparam name='T'> /// The type of item contained within the list. /// </typeparam> /// <remarks> /// <para> /// See the documentation of this type for detailled information on how this works and what it does. /// </para> /// </remarks> public static ICollection <T> GetOrInit <T>(ref ICollection <T> wrapper, ref ICollection <T> original, Expression <Func <T, object> > referenceProperty, object referenceItem) where T : class { EventBoundCollectionWrapper <T> typedList = wrapper as EventBoundCollectionWrapper <T>; if (typedList == null || !typedList.IsWrapping(original)) { original = original ?? new List <T>(); wrapper = GetOrInit(original, referenceProperty, referenceItem); } return(wrapper); }
/// <summary> /// Initialises and returns a new list wrapper, wrapping the given <paramref name="original"/> collection. /// </summary> /// <returns> /// A generic ICollection, with added addition and removal handlers. /// </returns> /// <param name='original'> /// The original/source list. /// </param> /// <param name='referenceProperty'> /// An expression indicating a property upon the contained type. /// </param> /// <param name='referenceItem'> /// The reference item to be stored in the <paramref name="referenceProperty"/>. /// </param> /// <typeparam name='T'> /// The type of item contained within the list. /// </typeparam> private static EventBoundCollectionWrapper <T> GetOrInit <T>(ICollection <T> original, Expression <Func <T, object> > referenceProperty, object referenceItem) where T : class { if (original == null) { throw new ArgumentNullException("original"); } EventBoundCollectionWrapper <T> output = original as EventBoundCollectionWrapper <T>; if (output == null) { PropertyInfo propInfo = Reflect.Property(referenceProperty); output = original.WrapWithBeforeActions((list, item) => BeforeAdd(list, item, propInfo, referenceItem), (list, item) => BeforeRemove(list, item, propInfo)); } return(output); }