| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 | #if XFORMSnamespace Caliburn.Micro.Core.Xamarin.Forms#elsenamespace Caliburn.Micro#endif {#if WinRT    using System.Linq;    using Windows.UI.Xaml;    using System.Reflection;#elif XFORMS    using UIElement = global::Xamarin.Forms.Element;    using FrameworkElement = global::Xamarin.Forms.VisualElement;    using DependencyProperty = global::Xamarin.Forms.BindableProperty;    using DependencyObject = global::Xamarin.Forms.BindableObject;#else    using Caliburn.Micro.Core;    using System.Windows;#endif    /// <summary>    ///   A host for action related attached properties.    /// </summary>    public static class Action {        static readonly ILog Log = LogManager.GetLog(typeof(Action));        /// <summary>        ///   A property definition representing the target of an <see cref="ActionMessage" /> . The DataContext of the element will be set to this instance.        /// </summary>        public static readonly DependencyProperty TargetProperty =            DependencyPropertyHelper.RegisterAttached(                "Target",                typeof(object),                typeof(Action),                null,                 OnTargetChanged                );        /// <summary>        ///   A property definition representing the target of an <see cref="ActionMessage" /> . The DataContext of the element is not set to this instance.        /// </summary>        public static readonly DependencyProperty TargetWithoutContextProperty =            DependencyPropertyHelper.RegisterAttached(                "TargetWithoutContext",                typeof(object),                typeof(Action),                null,                 OnTargetWithoutContextChanged                );        /// <summary>        ///   Sets the target of the <see cref="ActionMessage" /> .        /// </summary>        /// <param name="d"> The element to attach the target to. </param>        /// <param name="target"> The target for instances of <see cref="ActionMessage" /> . </param>        public static void SetTarget(DependencyObject d, object target) {            d.SetValue(TargetProperty, target);        }        /// <summary>        ///   Gets the target for instances of <see cref="ActionMessage" /> .        /// </summary>        /// <param name="d"> The element to which the target is attached. </param>        /// <returns> The target for instances of <see cref="ActionMessage" /> </returns>        public static object GetTarget(DependencyObject d) {            return d.GetValue(TargetProperty);        }        /// <summary>        ///   Sets the target of the <see cref="ActionMessage" /> .        /// </summary>        /// <param name="d"> The element to attach the target to. </param>        /// <param name="target"> The target for instances of <see cref="ActionMessage" /> . </param>        /// <remarks>        ///   The DataContext will not be set.        /// </remarks>        public static void SetTargetWithoutContext(DependencyObject d, object target) {            d.SetValue(TargetWithoutContextProperty, target);        }        /// <summary>        ///   Gets the target for instances of <see cref="ActionMessage" /> .        /// </summary>        /// <param name="d"> The element to which the target is attached. </param>        /// <returns> The target for instances of <see cref="ActionMessage" /> </returns>        public static object GetTargetWithoutContext(DependencyObject d) {            return d.GetValue(TargetWithoutContextProperty);        }        ///<summary>        ///  Checks if the <see cref="ActionMessage" /> -Target was set.        ///</summary>        ///<param name="element"> DependencyObject to check </param>        ///<returns> True if Target or TargetWithoutContext was set on <paramref name="element" /> </returns>        public static bool HasTargetSet(DependencyObject element) {            if (GetTarget(element) != null || GetTargetWithoutContext(element) != null)                return true;#if XFORMS            return false;#else            var frameworkElement = element as FrameworkElement;            if (frameworkElement == null)                return false;            return ConventionManager.HasBinding(frameworkElement, TargetProperty)                   || ConventionManager.HasBinding(frameworkElement, TargetWithoutContextProperty);#endif        }#if !XFORMS        ///<summary>        ///  Uses the action pipeline to invoke the method.        ///</summary>        ///<param name="target"> The object instance to invoke the method on. </param>        ///<param name="methodName"> The name of the method to invoke. </param>        ///<param name="view"> The view. </param>        ///<param name="source"> The source of the invocation. </param>        ///<param name="eventArgs"> The event args. </param>        ///<param name="parameters"> The method parameters. </param>        public static void Invoke(object target, string methodName, DependencyObject view = null, FrameworkElement source = null, object eventArgs = null, object[] parameters = null) {            var message = new ActionMessage {MethodName = methodName};            var context = new ActionExecutionContext {                Target = target,#if WinRT                Method = target.GetType().GetRuntimeMethods().Single(m => m.Name == methodName),#else                Method = target.GetType().GetMethod(methodName),#endif                Message = message,                View = view,                Source = source,                EventArgs = eventArgs            };            if (parameters != null) {                parameters.Apply(x => context.Message.Parameters.Add(x as Parameter ?? new Parameter { Value = x }));            }            ActionMessage.InvokeAction(context);            // This is a bit of hack but keeps message being garbage collected            Log.Info("Invoking action {0} on {1}.", message.MethodName, target);        }#endif        static void OnTargetWithoutContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {            SetTargetCore(e, d, false);        }        static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {            SetTargetCore(e, d, true);        }        static void SetTargetCore(DependencyPropertyChangedEventArgs e, DependencyObject d, bool setContext) {            if (e.NewValue == e.OldValue || (Execute.InDesignMode && e.NewValue is string)) {                return;            }            var target = e.NewValue;            var containerKey = e.NewValue as string;            if (containerKey != null) {                target = IoC.GetInstance(null, containerKey);            }#if XFORMS            Log.Info("Attaching message handler {0} to {1}.", target, d);            Message.SetHandler(d, target);            if (setContext && d is FrameworkElement) {                Log.Info("Setting DC of {0} to {1}.", d, target);                ((FrameworkElement)d).BindingContext = target;            }#else            if (setContext && d is FrameworkElement) {                Log.Info("Setting DC of {0} to {1}.", d, target);                ((FrameworkElement)d).DataContext = target;            }             Log.Info("Attaching message handler {0} to {1}.", target, d);             Message.SetHandler(d, target);#endif                    }    }}
 |