| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 | 
							- #if XFORMS
 
- namespace Caliburn.Micro.Core.Xamarin.Forms
 
- #else
 
- namespace Caliburn.Micro
 
- #endif 
 
- {
 
-     using System;
 
-     using System.Linq;
 
- #if WinRT
 
-     using System.Reflection;
 
-     using Windows.ApplicationModel;
 
-     using Windows.UI.Xaml;
 
-     using Windows.UI.Xaml.Controls;
 
-     using Windows.UI.Xaml.Markup;
 
-     using Windows.UI.Xaml.Media;
 
- #elif XFORMS
 
-     using System.Reflection;
 
-     using global::Xamarin.Forms;
 
-     using UIElement = global::Xamarin.Forms.Element;
 
-     using FrameworkElement = global::Xamarin.Forms.VisualElement;
 
-     using DependencyProperty = global::Xamarin.Forms.BindableProperty;
 
-     using DependencyObject = global::Xamarin.Forms.BindableObject;
 
-     using ContentControl = global::Xamarin.Forms.ContentView;
 
- #else
 
-     using System.ComponentModel;
 
-     using System.Windows;
 
-     using System.Windows.Controls;
 
-     using System.Windows.Markup;
 
-     using Caliburn.Micro.Core;
 
- #endif
 
-     /// <summary>
 
-     /// Hosts attached properties related to view models.
 
-     /// </summary>
 
-     public static class View {
 
-         static readonly ILog Log = LogManager.GetLog(typeof(View));
 
- #if WinRT || XFORMS
 
-         const string DefaultContentPropertyName = "Content";
 
- #else
 
-         static readonly ContentPropertyAttribute DefaultContentProperty = new ContentPropertyAttribute("Content");
 
- #endif
 
-         /// <summary>
 
-         /// A dependency property which allows the framework to track whether a certain element has already been loaded in certain scenarios.
 
-         /// </summary>
 
-         public static readonly DependencyProperty IsLoadedProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "IsLoaded",
 
-                 typeof(bool),
 
-                 typeof(View),
 
-                 false
 
-                 );
 
-         /// <summary>
 
-         /// A dependency property which marks an element as a name scope root.
 
-         /// </summary>
 
-         public static readonly DependencyProperty IsScopeRootProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "IsScopeRoot",
 
-                 typeof(bool),
 
-                 typeof(View),
 
-                 false
 
-                 );
 
-         /// <summary>
 
-         /// A dependency property which allows the override of convention application behavior.
 
-         /// </summary>
 
-         public static readonly DependencyProperty ApplyConventionsProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "ApplyConventions",
 
-                 typeof(bool?),
 
-                 typeof(View)
 
-                 );
 
-         /// <summary>
 
-         /// A dependency property for assigning a context to a particular portion of the UI.
 
-         /// </summary>
 
-         public static readonly DependencyProperty ContextProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "Context",
 
-                 typeof(object),
 
-                 typeof(View),
 
-                 null, 
 
-                 OnContextChanged
 
-                 );
 
-         /// <summary>
 
-         /// A dependency property for attaching a model to the UI.
 
-         /// </summary>
 
-         public static DependencyProperty ModelProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "Model",
 
-                 typeof(object),
 
-                 typeof(View),
 
-                 null, 
 
-                 OnModelChanged
 
-                 );
 
-         /// <summary>
 
-         /// Used by the framework to indicate that this element was generated.
 
-         /// </summary>
 
-         public static readonly DependencyProperty IsGeneratedProperty =
 
-             DependencyPropertyHelper.RegisterAttached(
 
-                 "IsGenerated",
 
-                 typeof(bool),
 
-                 typeof(View),
 
-                 false
 
-                 );
 
-         /// <summary>
 
-         /// Executes the handler immediately if the element is loaded, otherwise wires it to the Loaded event.
 
-         /// </summary>
 
-         /// <param name="element">The element.</param>
 
-         /// <param name="handler">The handler.</param>
 
-         /// <returns>true if the handler was executed immediately; false otherwise</returns>
 
-         public static bool ExecuteOnLoad(FrameworkElement element, RoutedEventHandler handler) {
 
- #if XFORMS
 
-             handler(element, new RoutedEventArgs());
 
-             return true;
 
- #else
 
- #if SILVERLIGHT
 
-             if ((bool)element.GetValue(IsLoadedProperty)) {
 
- #elif WinRT
 
-             if (IsElementLoaded(element)) {
 
- #else
 
-             if(element.IsLoaded) {
 
- #endif
 
-                 handler(element, new RoutedEventArgs());
 
-                 return true;
 
-             }
 
-             RoutedEventHandler loaded = null;
 
-             loaded = (s, e) => {
 
-                 element.Loaded -= loaded;
 
- #if SILVERLIGHT
 
-                 element.SetValue(IsLoadedProperty, true);
 
- #endif
 
-                 handler(s, e);
 
-             };
 
-             element.Loaded += loaded;
 
-             return false;
 
- #endif
 
-         }
 
-         /// <summary>
 
-         /// Executes the handler when the element is unloaded.
 
-         /// </summary>
 
-         /// <param name="element">The element.</param>
 
-         /// <param name="handler">The handler.</param>
 
-         public static void ExecuteOnUnload(FrameworkElement element, RoutedEventHandler handler) {
 
- #if !XFORMS
 
-             RoutedEventHandler unloaded = null;
 
-             unloaded = (s, e) => {
 
-                 element.Unloaded -= unloaded;
 
-                 handler(s, e);
 
-             };
 
-             element.Unloaded += unloaded;
 
- #endif
 
-         }
 
- #if WinRT
 
-         /// <summary>
 
-         /// Determines whether the specified <paramref name="element"/> is loaded.
 
-         /// </summary>
 
-         /// <param name="element">The element.</param>
 
-         /// <returns>true if the element is loaded; otherwise, false.
 
-         /// </returns>
 
-         public static bool IsElementLoaded(FrameworkElement element) {
 
-             try
 
-             {
 
-                 if ((element.Parent ?? VisualTreeHelper.GetParent(element)) != null)
 
-                 {
 
-                     return true;
 
-                 }
 
-                 var rootVisual = Window.Current.Content;
 
-                 if (rootVisual != null)
 
-                 {
 
-                     return element == rootVisual;
 
-                 }
 
-                 return false;
 
-             }
 
-             catch
 
-             {
 
-                 return false;
 
-             }
 
-         }
 
- #endif
 
-         /// <summary>
 
-         /// Executes the handler the next time the elements's LayoutUpdated event fires.
 
-         /// </summary>
 
-         /// <param name="element">The element.</param>
 
-         /// <param name="handler">The handler.</param>
 
- #if WinRT
 
-         public static void ExecuteOnLayoutUpdated(FrameworkElement element, EventHandler<object> handler) {
 
-             EventHandler<object> onLayoutUpdate = null;
 
- #else
 
-         public static void ExecuteOnLayoutUpdated(FrameworkElement element, EventHandler handler) {
 
-             EventHandler onLayoutUpdate = null;
 
- #endif
 
- #if !XFORMS
 
-             onLayoutUpdate = (s, e) => {
 
-                 element.LayoutUpdated -= onLayoutUpdate;
 
-                 handler(element, e);
 
-             };
 
-             element.LayoutUpdated += onLayoutUpdate;
 
- #endif
 
-         }
 
-         /// <summary>
 
-         /// Used to retrieve the root, non-framework-created view.
 
-         /// </summary>
 
-         /// <param name="view">The view to search.</param>
 
-         /// <returns>The root element that was not created by the framework.</returns>
 
-         /// <remarks>In certain instances the services create UI elements.
 
-         /// For example, if you ask the window manager to show a UserControl as a dialog, it creates a window to host the UserControl in.
 
-         /// The WindowManager marks that element as a framework-created element so that it can determine what it created vs. what was intended by the developer.
 
-         /// Calling GetFirstNonGeneratedView allows the framework to discover what the original element was. 
 
-         /// </remarks>
 
-         public static Func<object, object> GetFirstNonGeneratedView = view => {
 
-             var dependencyObject = view as DependencyObject;
 
-             if (dependencyObject == null) {
 
-                 return view;
 
-             }
 
-             if ((bool)dependencyObject.GetValue(IsGeneratedProperty)) {
 
-                 if (dependencyObject is ContentControl) {
 
-                     return ((ContentControl)dependencyObject).Content;
 
-                 }
 
- #if WinRT || XFORMS
 
-                 var type = dependencyObject.GetType();
 
-                 var contentPropertyName = GetContentPropertyName(type);
 
-                 return type.GetRuntimeProperty(contentPropertyName)
 
-                     .GetValue(dependencyObject, null);
 
- #else
 
-                 var type = dependencyObject.GetType();
 
-                 var contentProperty = type.GetAttributes<ContentPropertyAttribute>(true)
 
-                                           .FirstOrDefault() ?? DefaultContentProperty;
 
-                 return type.GetProperty(contentProperty.Name)
 
-                     .GetValue(dependencyObject, null);
 
- #endif
 
-             }
 
-             return dependencyObject;
 
-         };
 
-         /// <summary>
 
-         /// Gets the convention application behavior.
 
-         /// </summary>
 
-         /// <param name="d">The element the property is attached to.</param>
 
-         /// <returns>Whether or not to apply conventions.</returns>
 
-         public static bool? GetApplyConventions(DependencyObject d) {
 
-             return (bool?)d.GetValue(ApplyConventionsProperty);
 
-         }
 
-         /// <summary>
 
-         /// Sets the convention application behavior.
 
-         /// </summary>
 
-         /// <param name="d">The element to attach the property to.</param>
 
-         /// <param name="value">Whether or not to apply conventions.</param>
 
-         public static void SetApplyConventions(DependencyObject d, bool? value) {
 
-             d.SetValue(ApplyConventionsProperty, value);
 
-         }
 
-         /// <summary>
 
-         /// Sets the model.
 
-         /// </summary>
 
-         /// <param name="d">The element to attach the model to.</param>
 
-         /// <param name="value">The model.</param>
 
-         public static void SetModel(DependencyObject d, object value) {
 
-             d.SetValue(ModelProperty, value);
 
-         }
 
-         /// <summary>
 
-         /// Gets the model.
 
-         /// </summary>
 
-         /// <param name="d">The element the model is attached to.</param>
 
-         /// <returns>The model.</returns>
 
-         public static object GetModel(DependencyObject d) {
 
-             return d.GetValue(ModelProperty);
 
-         }
 
-         /// <summary>
 
-         /// Gets the context.
 
-         /// </summary>
 
-         /// <param name="d">The element the context is attached to.</param>
 
-         /// <returns>The context.</returns>
 
-         public static object GetContext(DependencyObject d) {
 
-             return d.GetValue(ContextProperty);
 
-         }
 
-         /// <summary>
 
-         /// Sets the context.
 
-         /// </summary>
 
-         /// <param name="d">The element to attach the context to.</param>
 
-         /// <param name="value">The context.</param>
 
-         public static void SetContext(DependencyObject d, object value) {
 
-             d.SetValue(ContextProperty, value);
 
-         }
 
-         static void OnModelChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs args) {
 
-             if (args.OldValue == args.NewValue) {
 
-                 return;
 
-             }
 
-             if (args.NewValue != null) {
 
-                 var context = GetContext(targetLocation);
 
-                 
 
-                 var view = ViewLocator.LocateForModel(args.NewValue, targetLocation, context);
 
-                 // Trialing binding before setting content in Xamarin Forms
 
- #if XFORMS
 
-                 ViewModelBinder.Bind(args.NewValue, view, context);
 
- #endif
 
-                 if (!SetContentProperty(targetLocation, view)) {
 
-                     Log.Warn("SetContentProperty failed for ViewLocator.LocateForModel, falling back to LocateForModelType");
 
-                     view = ViewLocator.LocateForModelType(args.NewValue.GetType(), targetLocation, context);
 
-                     SetContentProperty(targetLocation, view);
 
-                 }
 
- #if !XFORMS
 
-                 ViewModelBinder.Bind(args.NewValue, view, context);
 
- #endif
 
-             }
 
-             else {
 
-                 SetContentProperty(targetLocation, args.NewValue);
 
-             }
 
-         }
 
-         static void OnContextChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs e) {
 
-             if (e.OldValue == e.NewValue) {
 
-                 return;
 
-             }
 
-             var model = GetModel(targetLocation);
 
-             if (model == null) {
 
-                 return;
 
-             }
 
-             var view = ViewLocator.LocateForModel(model, targetLocation, e.NewValue);
 
-             if (!SetContentProperty(targetLocation, view)) {
 
-                 Log.Warn("SetContentProperty failed for ViewLocator.LocateForModel, falling back to LocateForModelType");
 
-                 view = ViewLocator.LocateForModelType(model.GetType(), targetLocation, e.NewValue);
 
-                 SetContentProperty(targetLocation, view);
 
-             }
 
-             ViewModelBinder.Bind(model, view, e.NewValue);
 
-         }
 
-         static bool SetContentProperty(object targetLocation, object view) {
 
-             var fe = view as FrameworkElement;
 
-             if (fe != null && fe.Parent != null) {
 
-                 SetContentPropertyCore(fe.Parent, null);
 
-             }
 
-             return SetContentPropertyCore(targetLocation, view);
 
-         }
 
- #if WinRT || XFORMS
 
-         static bool SetContentPropertyCore(object targetLocation, object view) {
 
-             try {
 
-                 var type = targetLocation.GetType();
 
-                 var contentPropertyName = GetContentPropertyName(type);
 
-                 type.GetRuntimeProperty(contentPropertyName)
 
-                     .SetValue(targetLocation, view, null);
 
-                 return true;
 
-             }
 
-             catch (Exception e) {
 
-                 Log.Error(e);
 
-                 return false;
 
-             }
 
-         }
 
-         private static string GetContentPropertyName(Type type) {
 
-             var typeInfo = type.GetTypeInfo();
 
-             var contentProperty = typeInfo.GetCustomAttribute<ContentPropertyAttribute>();
 
-             
 
-             return contentProperty?.Name ?? DefaultContentPropertyName;
 
-         }
 
- #else
 
-         static bool SetContentPropertyCore(object targetLocation, object view) {
 
-             try {
 
-                 var type = targetLocation.GetType();
 
-                 var contentProperty = type.GetAttributes<ContentPropertyAttribute>(true)
 
-                                           .FirstOrDefault() ?? DefaultContentProperty;
 
-                 type.GetProperty(contentProperty.Name ?? DefaultContentProperty.Name)
 
-                     .SetValue(targetLocation, view, null);
 
-                 return true;
 
-             }
 
-             catch(Exception e) {
 
-                 Log.Error(e);
 
-                 return false;
 
-             }
 
-         }
 
- #endif
 
-         private static bool? inDesignMode;
 
-         /// <summary>
 
-         /// Gets a value that indicates whether the process is running in design mode.
 
-         /// </summary>
 
-         public static bool InDesignMode
 
-         {
 
-             get
 
-             {
 
-                 if (inDesignMode == null)
 
-                 {
 
- #if XFORMS
 
-                     inDesignMode = false;
 
- #elif WinRT
 
-                     inDesignMode = DesignMode.DesignModeEnabled;
 
- #elif SILVERLIGHT
 
-                     inDesignMode = DesignerProperties.IsInDesignTool;
 
- #else
 
-                     var descriptor = DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement));
 
-                     inDesignMode = (bool)descriptor.Metadata.DefaultValue;
 
- #endif
 
-                 }
 
-                 return inDesignMode.GetValueOrDefault(false);
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |