コード例 #1
0
        /// <summary>
        /// Creates the delegate with requested type from a method.
        /// </summary>
        /// <param name="methodName">The method name that can be used as a delegate.</param>
        /// <param name="sourceObject">The source object that contains a method.</param>
        /// <param name="desiredDelegateType">The delegate type.</param>
        /// <returns></returns>
        public static Object EventHandlerDelegateFromMethod(string methodName, object sourceObject, Type desiredDelegateType)
        {
            MethodInfo methodInfo = sourceObject.GetMethodInfo(methodName);

            if (methodInfo == null)
            {
                List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceObject);
                foreach (var model in locatedViewModels)
                {
                    methodInfo = model.Item2.GetMethodInfo(methodName);
                    if (methodInfo != null)
                    {
                        sourceObject = model.Item2;
                        break;
                    }
                }
            }
            if (methodInfo == null)
            {
                throw new ArgumentException("DelegateFromMethod - cannot resolve method  " + methodName);
            }
            return(EventHandlerDelegateFromMethodInfo(sourceObject, desiredDelegateType, methodInfo));
        }
コード例 #2
0
        internal object ResolvePropertyValues(object sourceBaseProvided)
        {
            if (sourceBaseProvided == null)
            {
                return(null);
            }
            EventInfo           outerEvent         = null;
            PropertyInfo        outerProperty      = null;
            Action <object>     executeDelegate    = null;
            Func <object, bool> canExecuteDelegate = null;

            Type type = sourceBaseProvided.GetType();

            if ((!String.IsNullOrEmpty(ExecuteMethodName)) && (!String.IsNullOrEmpty(ExecutePropertyName)))
            {
                throw new ArgumentException("BindCommandBase - Should be set only one property 'ExecuteMethodName' or 'ExecutePropertyName'");
            }

            if ((!String.IsNullOrEmpty(CanExecuteBooleanPropertyName)) &&
                (!String.IsNullOrEmpty(CanExecuteMethodName) ||
                 !String.IsNullOrEmpty(CanExecutePropertyName) ||
                 !String.IsNullOrEmpty(EventToInvokeCanExecuteChanged) ||
                 !String.IsNullOrEmpty(PropertyActionCanExecuteChanged)))
            {
                throw new ArgumentException("BindCommandBase - Should be set only one property 'CanExecuteBooleanPropertyName'");
            }

            if ((!String.IsNullOrEmpty(CanExecuteMethodName)) && (!String.IsNullOrEmpty(CanExecutePropertyName)))
            {
                throw new ArgumentException("BindCommandBase - Should be set only one property 'CanExecuteMethodName' or 'CanExecutePropertyName'");
            }

            if ((!String.IsNullOrEmpty(EventToInvokeCanExecuteChanged)) && (!String.IsNullOrEmpty(PropertyActionCanExecuteChanged)))
            {
                throw new ArgumentException("BindCommandBase - Should be set only one property 'EventToInvokeCanExecuteChanged' or 'PropertyActionCanExecuteChanged'");
            }

            if (!String.IsNullOrEmpty(ExecuteMethodName))
            {
                MethodInfo executeMethod = type.GetMethodInfo(ExecuteMethodName);
                if (executeMethod == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        executeMethod = model.Item2.GetMethodInfo(ExecuteMethodName);
                        if (executeMethod != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }
                if (executeMethod == null)
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'ExecuteMethodName' method  " + ExecuteMethodName);
                }

                if (executeMethod.IsStatic)
                {
#if WINDOWS_UWP
                    executeDelegate = (Action <object>)executeMethod.CreateDelegate(typeof(Action <object>));
#else
                    executeDelegate = (Action <object>)Delegate.CreateDelegate(typeof(Action <object>), executeMethod);
#endif
                }
                else
                {
#if WINDOWS_UWP
                    executeDelegate = (Action <object>)executeMethod.CreateDelegate(typeof(Action <object>), sourceBaseProvided);
#else
                    executeDelegate = (Action <object>)Delegate.CreateDelegate(typeof(Action <object>), sourceBaseProvided, executeMethod);
#endif
                }
            }
            else if (!String.IsNullOrEmpty(ExecutePropertyName))
            {
                // Get the property info and check the property type.
                PropertyInfo methodProperty = type.GetPropertyInfo(ExecutePropertyName);

                if (methodProperty == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        methodProperty = model.Item2.GetPropertyInfo(ExecutePropertyName);
                        if (methodProperty != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }
                if ((methodProperty == null) || (methodProperty.PropertyType != typeof(Action <object>)))
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'ExecutePropertyName' property " + ExecuteMethodName);
                }
                executeDelegate = (Action <object>)methodProperty.GetValue(sourceBaseProvided, null);
            }


            if (!String.IsNullOrEmpty(CanExecuteBooleanPropertyName))
            {
                PropertyInfo booleanProperty = type.GetPropertyInfo(CanExecuteBooleanPropertyName);
                if (booleanProperty == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        booleanProperty = model.Item2.GetPropertyInfo(CanExecuteBooleanPropertyName);
                        if (booleanProperty != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }
                if ((booleanProperty == null) || (booleanProperty.PropertyType != typeof(Boolean)))
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'CanExecuteBooleanPropertyName' property  " + CanExecuteBooleanPropertyName);
                }
                ResolvedCommand = WeakBinding ? new WeakCommandHandlerProxy(executeDelegate, booleanProperty, sourceBaseProvided)
                : new CommandHandlerProxy(executeDelegate, booleanProperty, sourceBaseProvided);

                return(ResolvedCommand);
            }
            if (!String.IsNullOrEmpty(CanExecuteMethodName))
            {
                MethodInfo canExecuteMethod = type.GetMethodInfo(CanExecuteMethodName);
                if (canExecuteMethod == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        canExecuteMethod = model.Item2.GetMethodInfo(CanExecuteMethodName);
                        if (canExecuteMethod != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }

                if (canExecuteMethod == null)
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'CanExecuteMethodName' method " + CanExecuteMethodName);
                }
                if (canExecuteMethod.IsStatic)
                {
#if WINDOWS_UWP
                    canExecuteDelegate = (Func <object, bool>)canExecuteMethod.CreateDelegate(typeof(Func <object, bool>));
#else
                    canExecuteDelegate = (Func <object, bool>)Delegate.CreateDelegate(typeof(Func <object, bool>), canExecuteMethod);
#endif
                }
                else
                {
#if WINDOWS_UWP
                    canExecuteDelegate = (Func <object, bool>)canExecuteMethod.CreateDelegate(typeof(Func <object, bool>), sourceBaseProvided);
#else
                    canExecuteDelegate = (Func <object, bool>)Delegate.CreateDelegate(typeof(Func <object, bool>), sourceBaseProvided, canExecuteMethod);
#endif
                }
            }
            else if (!String.IsNullOrEmpty(CanExecutePropertyName))
            {
                PropertyInfo methodProperty = type.GetPropertyInfo(CanExecutePropertyName);
                if (methodProperty == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        methodProperty = model.Item2.GetPropertyInfo(CanExecutePropertyName);
                        if (methodProperty != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }
                if ((methodProperty == null) || (methodProperty.PropertyType != typeof(Func <object, bool>)))
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'CanExecutePropertyName' property  " + CanExecuteMethodName);
                }
                canExecuteDelegate = (Func <object, bool>)methodProperty.GetValue(sourceBaseProvided, null);
            }

            if (!String.IsNullOrEmpty(EventToInvokeCanExecuteChanged))
            {
                outerEvent = type.GetEventInfo(EventToInvokeCanExecuteChanged);
                if (outerEvent == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        outerEvent = model.Item2.GetEventInfo(EventToInvokeCanExecuteChanged);
                        if (outerEvent != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }

                if (outerEvent == null)
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'EventToInvokeCanExecuteChanged' event " + EventToInvokeCanExecuteChanged);
                }
            }

            if (!String.IsNullOrEmpty(PropertyActionCanExecuteChanged))
            {
                outerProperty = type.GetPropertyInfo(PropertyActionCanExecuteChanged);
                if (outerProperty == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                    foreach (var model in locatedViewModels)
                    {
                        outerProperty = model.Item2.GetPropertyInfo(PropertyActionCanExecuteChanged);
                        if (outerProperty != null)
                        {
                            sourceBaseProvided = model.Item2;
                            type = model.Item1;
                            break;
                        }
                    }
                }

                if (outerProperty == null)
                {
                    throw new ArgumentException("BindCommandBase - cannot resolve 'PropertyActionCanExecuteChanged' property " + PropertyActionCanExecuteChanged);
                }
            }

            if ((outerEvent != null) || (outerProperty != null))
            {
                if (outerEvent != null)
                {
                    ResolvedCommand = WeakBinding ? new WeakCommandHandlerProxy(executeDelegate, canExecuteDelegate, outerEvent, sourceBaseProvided)
                              : new CommandHandlerProxy(executeDelegate, canExecuteDelegate, outerEvent, sourceBaseProvided);
                }
                else if (outerProperty != null)
                {
                    ResolvedCommand = WeakBinding ? new WeakCommandHandlerProxy(executeDelegate, canExecuteDelegate, outerProperty, sourceBaseProvided)
                              : new CommandHandlerProxy(executeDelegate, canExecuteDelegate, outerProperty, sourceBaseProvided);
                }

                return(ResolvedCommand);
            }

            ResolvedCommand = WeakBinding ? new WeakCommandHandlerProxy(executeDelegate, canExecuteDelegate)
                       : new CommandHandlerProxy(executeDelegate, canExecuteDelegate);

            return(ResolvedCommand);
        }
コード例 #3
0
        /// <summary>
        /// Validates an object if it is match to the type or/and members content.
        /// </summary>
        /// <param name="value">The object to validate.</param>
        /// <param name="methodName">The method name in the dependency property object.
        /// The properties will be scan up over the visual tree until the  method name will be in math  to the method in the object
        /// that represented by a property value.</param>
        /// <param name="propertyName">The property name in the dependency property object.
        /// The properties will be scan up over the visual tree until the  property name will be in math  to the property in the object
        /// that represented by a property value.</param>
        /// <param name="eventName">The event name in the dependency property object.
        /// The properties will be scan up over the visual tree until the  event name will be in math  to the event in the object
        /// that represented by a property value.</param>
        /// <param name="matchType">The type which should match with a property or event or method name or by it self.</param>
        /// <returns>Returns true if it has a match.</returns>
        static public bool ValidateValue(object value, string methodName, string propertyName = null, string eventName = null, Type matchType = null)
        {
            if (string.IsNullOrEmpty(methodName) && string.IsNullOrEmpty(propertyName) && string.IsNullOrEmpty(eventName) && matchType == null)
            {
                return(true);
            }

            if (string.IsNullOrEmpty(methodName) && string.IsNullOrEmpty(propertyName) && string.IsNullOrEmpty(eventName))
            {
#if WINDOWS_UWP
                return(value.GetType() == matchType || value.GetType().GetTypeInfo().IsSubclassOf(matchType));
#else
                return(value.GetType() == matchType || value.GetType().IsSubclassOf(matchType));
#endif
            }

            // Deep check the property object with the method name
            if (!string.IsNullOrEmpty(methodName))
            {
                MethodInfo methodInfo = value.GetMethodInfo(methodName);
                if (methodInfo == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(value);
                    foreach (var model in locatedViewModels)
                    {
                        methodInfo = model.Item2.GetMethodInfo(methodName);
                        if (methodInfo != null)
                        {
                            break;
                        }
                    }
                }
                if (methodInfo != null)
                {
                    if (matchType != null)
                    {
#if WINDOWS_UWP
                        return(value.GetType() == matchType || value.GetType().GetTypeInfo().IsSubclassOf(matchType));
#else
                        return(value.GetType() == matchType || value.GetType().IsSubclassOf(matchType));
#endif
                    }

                    // Return only if it has a math in the object
                    return(true);
                }
            }
            // Deep check the property object with the property name
            if (!string.IsNullOrEmpty(propertyName))
            {
                PropertyInfo propertyInfo = value.GetPropertyInfo(propertyName);
                if (propertyInfo == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(value);
                    foreach (var model in locatedViewModels)
                    {
                        propertyInfo = model.Item2.GetPropertyInfo(propertyName);
                        if (propertyInfo != null)
                        {
                            break;
                        }
                    }
                }
                if (propertyInfo != null)
                {
                    if (matchType != null)
                    {
#if WINDOWS_UWP
                        return(value.GetType() == matchType || value.GetType().GetTypeInfo().IsSubclassOf(matchType));
#else
                        return(value.GetType() == matchType || value.GetType().IsSubclassOf(matchType));
#endif
                    }
                    // Return only if it has a math in the object
                    return(true);
                }
            }
            // Deep check the property object with the event name
            if (!string.IsNullOrEmpty(eventName))
            {
                EventInfo eventInfo = value.GetEventInfo(eventName);
                if (eventInfo == null)
                {
                    List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(value);
                    foreach (var model in locatedViewModels)
                    {
                        eventInfo = model.Item2.GetEventInfo(eventName);
                        if (eventInfo != null)
                        {
                            break;
                        }
                    }
                }
                if (eventInfo != null)
                {
                    if (matchType != null)
                    {
#if WINDOWS_UWP
                        return(value.GetType() == matchType || value.GetType().GetTypeInfo().IsSubclassOf(matchType));
#else
                        return(value.GetType() == matchType || value.GetType().IsSubclassOf(matchType));
#endif
                    }
                    // Return only if it has a math in the object
                    return(true);
                }
            }

            return(false);
        }
コード例 #4
0
        /// <summary>
        /// Returns an object that should be set on the property where this extension is applied.
        /// </summary>
        /// <param name="serviceProvider">An object that can provide services for the markup extension.</param>
        /// <returns>The object value to set on the property where the markup extension provided value is evaluated.</returns>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            // ReSharper disable SuggestUseVarKeywordEvident
            IProvideValueTarget valueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

            // ReSharper restore SuggestUseVarKeywordEvident

            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetProperty != null))
            {
                TargetObject   = valueTarget.TargetObject;
                TargetProperty = valueTarget.TargetProperty;
            }

            Type desiredDelegateType = typeof(RoutedEventHandler);

#if !WINDOWS_UWP
            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetObject is FakeCollection) && (valueTarget.TargetProperty == null))
            {
                // XAML WinRt doesn't call ProvideValue() but WPF always does call ProvideVlue()
                // WPF - for case of the FakeCollectionEventHandler as a target object returns the instance of the object.
                // WPF - will call the instance of this object to resolve event handler delegate
                return(this);
            }

            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetProperty == BindXAML.AddEventsProperty))
            {
                throw new ArgumentException("BindEventHandlerBase - Coding Error Direct access to attached property XAML Parser.");
            }

            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetProperty != null) && (valueTarget.TargetProperty is MethodInfo))
            {
                // Support for a single attached property for WPF
                // XAML WinRt doesn't call ProvideValue() but WPF always does call ProvideVlue()
                // In this case if use the single attached property we have to demonstrate
                // Extract desired type from add method (object, handler)
                MethodInfo mf = valueTarget.TargetProperty as MethodInfo;
                if (mf.GetParameters().Length == 2)
                {
                    var pfs = mf.GetParameters();
                    desiredDelegateType = pfs[1].ParameterType;
                }
                else
                {
                    return(this);
                }
            }
            else
#endif

            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetProperty != null))
            {
                if (!(valueTarget.TargetProperty is MethodInfo))
                {
                    // Should not be check if bind in style of attached property
                    if (!(valueTarget.TargetProperty is EventInfo))
                    {
                        throw new ArgumentException("BindEventHandlerBase - Target should be 'event' type class member");
                    }
                    desiredDelegateType = (valueTarget.TargetProperty as EventInfo).EventHandlerType;
                }
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                var    info = this.GetMethodInfo("DesignRoutedEventHandler");
                object designProvidedValue;
                if (info.IsStatic)
                {
#if WINDOWS_UWP
                    designProvidedValue = info.CreateDelegate(desiredDelegateType);
#else
                    designProvidedValue = Delegate.CreateDelegate(desiredDelegateType, info);
#endif
                }
                else
                {
#if WINDOWS_UWP
                    designProvidedValue = info.CreateDelegate(desiredDelegateType, this);
#else
                    designProvidedValue = Delegate.CreateDelegate(desiredDelegateType, this, info);
#endif
                }
                // Cannot correctly resolve in the design mode the source.
                return(designProvidedValue);
            }

            object sourceBaseProvided = ObtainSourceObject(serviceProvider);

            if ((!String.IsNullOrEmpty(PropertyName)) && (!String.IsNullOrEmpty(MethodName)))
            {
                throw new ArgumentException("BindEventHandlerBase - Should be set only one property 'MethodName' or 'PropertyName'");
            }

            if ((String.IsNullOrEmpty(PropertyName)) && (String.IsNullOrEmpty(MethodName)))
            {
                throw new ArgumentException("BindEventHandlerBase - Should be set one of properties 'MethodName' or 'PropertyName'");
            }

            if (!String.IsNullOrEmpty(PropertyName))
            {
                if (sourceBaseProvided == null)
                {
                    if (this is BindEventHandler)
                    {
                        // Set the loaded event and requested event because we don't know which is going to be called first
                        ResolvedEventHandler = DataContextProxyRoutedEventHandler.CreateProxyDelegate(desiredDelegateType, MethodName, PropertyName);
                    }
                    else
                    {
                        throw new ArgumentException("BindEventHandlerBase - cannot resolve 'PropertyName' property  " + PropertyName);
                    }
                }
                else
                {
                    var propertyInfo = sourceBaseProvided.GetPropertyInfo(PropertyName);
                    if (propertyInfo == null)
                    {
                        List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                        foreach (var model in locatedViewModels)
                        {
                            propertyInfo = model.Item2.GetPropertyInfo(PropertyName);
                            if (propertyInfo != null)
                            {
                                sourceBaseProvided = model.Item2;
                                break;
                            }
                        }
                    }
                    if (propertyInfo == null)
                    {
                        throw new ArgumentException("BindEventHandlerBase - cannot resolve 'PropertyName' property  " + PropertyName);
                    }
                    ResolvedEventHandler = propertyInfo.GetValue(sourceBaseProvided, null);
                }
            }

            if (!String.IsNullOrEmpty(MethodName))
            {
                if (sourceBaseProvided == null)
                {
                    if (this is BindEventHandler)
                    {
                        // Set the loaded event and requested event because we don't know which is going to be called first
                        ResolvedEventHandler = DataContextProxyRoutedEventHandler.CreateProxyDelegate(desiredDelegateType, MethodName, PropertyName);
                    }
                    else
                    {
                        throw new ArgumentException("BindEventHandlerBase - cannot resolve 'MethodName' property  " + MethodName);
                    }
                }
                else
                {
                    //Get all appenders
                    MethodInfo methodInfo = sourceBaseProvided.GetMethodInfo(MethodName);
                    if (methodInfo == null)
                    {
                        List <Tuple <Type, object> > locatedViewModels = BindHelper.LocateAppendedViewModels(sourceBaseProvided);
                        foreach (var model in locatedViewModels)
                        {
                            methodInfo = model.Item2.GetMethodInfo(MethodName);
                            if (methodInfo != null)
                            {
                                sourceBaseProvided = model.Item2;
                                break;
                            }
                        }
                    }

                    if (methodInfo == null)
                    {
                        throw new ArgumentException("BindEventHandlerBase - cannot resolve 'MethodName' property  " + MethodName);
                    }

                    if (methodInfo.IsStatic)
                    {
#if WINDOWS_UWP
                        ResolvedEventHandler = methodInfo.CreateDelegate(desiredDelegateType);
#else
                        ResolvedEventHandler = Delegate.CreateDelegate(desiredDelegateType, methodInfo);
#endif
                    }
                    else
                    {
#if WINDOWS_UWP
                        ResolvedEventHandler = methodInfo.CreateDelegate(desiredDelegateType, sourceBaseProvided);
#else
                        ResolvedEventHandler = Delegate.CreateDelegate(desiredDelegateType, sourceBaseProvided, methodInfo);
#endif
                    }
                }
            }


            return(ResolvedEventHandler);
        }