| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 | namespace Caliburn.Micro.Core {    using System;    using System.Collections.Generic;    /// <summary>    /// A base implementation of <see cref = "IViewAware" /> which is capable of caching views by context.    /// </summary>    public class ViewAware : PropertyChangedBase, IViewAware {        readonly IDictionary<object, object> views;        /// <summary>        /// The default view context.        /// </summary>        public static readonly object DefaultContext = new object();        /// <summary>        /// The view chache for this instance.        /// </summary>        protected IDictionary<object, object> Views {            get { return views; }        }        /// <summary>        /// Creates an instance of <see cref="ViewAware"/>.        /// </summary>        public ViewAware() {            views = new WeakValueDictionary<object, object>();        }        /// <summary>        /// Raised when a view is attached.        /// </summary>        public event EventHandler<ViewAttachedEventArgs> ViewAttached = delegate { };        void IViewAware.AttachView(object view, object context) {            Views[context ?? DefaultContext] = view;            var nonGeneratedView = PlatformProvider.Current.GetFirstNonGeneratedView(view);            PlatformProvider.Current.ExecuteOnFirstLoad(nonGeneratedView, OnViewLoaded);            OnViewAttached(nonGeneratedView, context);            ViewAttached(this, new ViewAttachedEventArgs {View = nonGeneratedView, Context = context});            var activatable = this as IActivate;            if (activatable == null || activatable.IsActive) {                PlatformProvider.Current.ExecuteOnLayoutUpdated(nonGeneratedView, OnViewReady);            }            else {                AttachViewReadyOnActivated(activatable, nonGeneratedView);            }        }        static void AttachViewReadyOnActivated(IActivate activatable, object nonGeneratedView) {            var viewReference = new WeakReference(nonGeneratedView);            EventHandler<ActivationEventArgs> handler = null;            handler = (s, e) => {                ((IActivate)s).Activated -= handler;                var view = viewReference.Target;                if (view != null) {                    PlatformProvider.Current.ExecuteOnLayoutUpdated(view, ((ViewAware)s).OnViewReady);                }            };            activatable.Activated += handler;        }        /// <summary>        /// Called when a view is attached.        /// </summary>        /// <param name="view">The view.</param>        /// <param name="context">The context in which the view appears.</param>        protected virtual void OnViewAttached(object view, object context) {        }        /// <summary>        /// Called when an attached view's Loaded event fires.        /// </summary>        /// <param name = "view"></param>        protected virtual void OnViewLoaded(object view) {        }        /// <summary>        /// Called the first time the page's LayoutUpdated event fires after it is navigated to.        /// </summary>        /// <param name = "view"></param>        protected virtual void OnViewReady(object view) {        }        /// <summary>        /// Gets a view previously attached to this instance.        /// </summary>        /// <param name = "context">The context denoting which view to retrieve.</param>        /// <returns>The view.</returns>        public virtual object GetView(object context = null) {            object view;            Views.TryGetValue(context ?? DefaultContext, out view);            return view;        }    }}
 |