| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 | namespace Caliburn.Micro {    using System.Collections.Specialized;    using System.Linq;    using System.Windows;    using System.Windows.Interactivity;    using Caliburn.Micro.Core;    /// <summary>    /// A collection that can exist as part of a behavior.    /// </summary>    /// <typeparam name="T">The type of item in the attached collection.</typeparam>    public class AttachedCollection<T> : FreezableCollection<T>, IAttachedObject        where T : DependencyObject, IAttachedObject {        DependencyObject associatedObject;        /// <summary>        /// Creates an instance of <see cref="AttachedCollection{T}"/>        /// </summary>        public AttachedCollection() {            ((INotifyCollectionChanged)this).CollectionChanged += OnCollectionChanged;        }        /// <summary>        /// Attached the collection.        /// </summary>        /// <param name="dependencyObject">The dependency object to attach the collection to.</param>        public void Attach(DependencyObject dependencyObject) {            WritePreamble();            associatedObject = dependencyObject;            WritePostscript();            this.Apply(x => x.Attach(associatedObject));        }        /// <summary>        /// Detaches the collection.        /// </summary>        public void Detach() {            this.Apply(x => x.Detach());            WritePreamble();            associatedObject = null;            WritePostscript();        }        DependencyObject IAttachedObject.AssociatedObject {            get { return associatedObject; }        }        /// <summary>        /// Called when an item is added from the collection.        /// </summary>        /// <param name="item">The item that was added.</param>        protected virtual void OnItemAdded(T item) {            if (associatedObject != null)                item.Attach(associatedObject);        }        /// <summary>        /// Called when an item is removed from the collection.        /// </summary>        /// <param name="item">The item that was removed.</param>        protected virtual void OnItemRemoved(T item) {            if(item.AssociatedObject != null)                item.Detach();        }        void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {            switch(e.Action) {                case NotifyCollectionChangedAction.Add:                    e.NewItems.OfType<T>().Where(x => !Contains(x)).Apply(OnItemAdded);                    break;                case NotifyCollectionChangedAction.Remove:                    e.OldItems.OfType<T>().Apply(OnItemRemoved);                    break;                case NotifyCollectionChangedAction.Replace:                    e.OldItems.OfType<T>().Apply(OnItemRemoved);                    e.NewItems.OfType<T>().Where(x => !Contains(x)).Apply(OnItemAdded);                    break;                case NotifyCollectionChangedAction.Reset:                    this.Apply(OnItemRemoved);                    this.Apply(OnItemAdded);                    break;            }        }    }}
 |