Sic05/FrameworkLocal/UIClient/Caliburn.Micro/Core/ViewAware.cs

99 lines
3.6 KiB
C#

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;
}
}
}