Пример #1
0
        void DelayLocateDataContext(object obj, RoutedEventArgs args)
        {
            var frameworkElement = TargetObject as FrameworkElement;

            if (frameworkElement != null)
            {
                frameworkElement.Loaded -= DelayLocateDataContext;
                object dataContext;
                dataContext = BindHelper.LocateValidDependencyPropertyByAllTrees(TargetObject as DependencyObject, FrameworkElement.DataContextProperty, MethodName, PropertyName);
                if (dataContext != null)
                {
#if !WINDOWS_UWP
                    if (TargetProperty is DependencyProperty)
                    {
                        frameworkElement.SetValue((DependencyProperty)TargetProperty, dataContext);
                    }
#else
                    if (TargetProperty as PropertyInfo != null)
                    {
                        ((PropertyInfo)TargetProperty).SetValue(TargetObject, dataContext);
                    }
#endif
                }

                frameworkElement.Loaded -= DelayLocateDataContext;
            }
        }
Пример #2
0
        /// <summary>
        /// Returns an object that should be set on the property where this extension is applied.
        /// </summary>
        /// <param name="serviceProvider">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>
        /// <exception cref="System.InvalidOperationException">serviceProvider was null, or failed to
        /// implement a required service.</exception>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            object obj = null;
            Type   typeToResolve;

            if (_dataContextType == null)
            {
                typeToResolve = typeof(object);
            }
            else if (_dataContextType is Type)
            {
                typeToResolve = (Type)_dataContextType;
            }
            else if (_dataContextType is String)
            {
#if !WINDOWS_UWP
                // ReSharper disable SuggestUseVarKeywordEvident
                IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
                // ReSharper restore SuggestUseVarKeywordEvident

                typeToResolve = BindHelper.ResolveTypeByName((string)_dataContextType);

                if ((service != null) && (typeToResolve == null))
                {
                    typeToResolve = service.Resolve((string)_dataContextType);
                }
#else
                typeToResolve = BindHelper.ResolveTypeByName((string)_dataContextType);
#endif
            }
            else
            {
                throw new ArgumentNullException("LocateDataContext - DataContextType can be 'Type' or 'String' or empty.");
            }

            // ReSharper disable SuggestUseVarKeywordEvident
            IProvideValueTarget serviceProvideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            // ReSharper restore SuggestUseVarKeywordEvident
            if ((serviceProvideValueTarget != null) && (serviceProvideValueTarget.TargetObject != null))
            {
                // Save targets for case delayed processing
                TargetObject   = serviceProvideValueTarget.TargetObject;
                TargetProperty = serviceProvideValueTarget.TargetProperty;

                if (!(serviceProvideValueTarget.TargetObject is DependencyObject))
                {
                    throw new AggregateException("LocateDataContext - Target of the markup extension must be the DependencyObject type.");
                }
                obj = BindHelper.LocateValidDependencyPropertyByAllTrees(serviceProvideValueTarget.TargetObject as DependencyObject, FrameworkElement.DataContextProperty, MethodName, PropertyName, null, typeToResolve);
                if (obj == null)
                {
                    var frameworkElement = TargetObject as FrameworkElement;
                    if (frameworkElement != null)
                    {
                        frameworkElement.Loaded += DelayLocateDataContext;
                    }
                }
            }
            return(obj);
        }
Пример #3
0
        /// <summary>
        /// Constructs the attribute for x:Name element and  target mapping.
        /// </summary>
        /// <param name="aliasName">Alias x:Name string. If it contains '_', it will be split on XAML x:Name element targets as well.</param>
        /// <param name="commaSeparatedTargets">XAML x:Name element targets separated by comma.</param>
        public ViewXNameSourceTargetMappingAttribute(string aliasName, string commaSeparatedTargets = "")
        {
            var aliasname = aliasName.TrimStart().TrimEnd();

            if (!string.IsNullOrEmpty(aliasname))
            {
                _alias = aliasname;
                if (!string.IsNullOrEmpty(_alias))
                {
                    var targets = commaSeparatedTargets.Split(',');
                    foreach (var item in targets)
                    {
                        var name = item.TrimStart().TrimEnd();
                        if (!string.IsNullOrEmpty(name))
                        {
                            if (BindHelper.ValidateElementName(name))
                            {
                                _targets.Add(name);
                            }
                        }
                    }
                }
            }
#if DEBUG
            if (String.IsNullOrEmpty(_alias) || _targets.Count == 0)
            {
                throw new InvalidOperationException("aliasName or commaSeparatedTargets was not defined.");
            }
#endif
        }
Пример #4
0
        /// <summary>
        /// Get a source object for binding.
        /// If it is not set on, by default the method will search the first defined DataContext property value.
        /// </summary>
        /// <param name="serviceProvider">Object that can provide services for the markup extension.</param>
        /// <returns>Reference to a source object.</returns>
        protected override object ObtainSourceObject(IServiceProvider serviceProvider)
        {
            // For WinRT we provide a valid targets through BindXAML class.
            if (Source == null)
            {
                // ReSharper disable SuggestUseVarKeywordEvident
                IProvideValueTarget service = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                // ReSharper restore SuggestUseVarKeywordEvident

                if ((service != null) && (service.TargetObject != null))
                {
                    if (DeepScanAllTrees)
                    {
                        return(BindHelper.LocateValidDependencyPropertyByAllTrees(service.TargetObject as DependencyObject, FrameworkElement.DataContextProperty, ExecuteMethodName, ExecutePropertyName));
                    }
                    else
                    {
                        return(BindHelper.LocateValidDependencyPropertyByAllTrees(service.TargetObject as DependencyObject, FrameworkElement.DataContextProperty));
                    }
                }
            }

            if (Source is string)
            {
            }

            return(Source);
        }
Пример #5
0
        /// <summary>
        /// The method which will be called for the attached dependency property when  the new element is added to a fake collection.
        /// </summary>
        /// <param name="dependencyObject">The target FrameworkElement.</param>
        /// <param name="item">The new object to add.</param>
        public static void ProcessAddPropertyChangeEventItems(DependencyObject dependencyObject, object item)
        {
            if ((item == null) || (dependencyObject == null))
            {
                return;
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }

            BindEventHandler bindItem = item as BindEventHandler;

            if (bindItem == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents accepts only BindEventHandlers Type instances ");
            }

            if (String.IsNullOrEmpty(bindItem.TargetPropertyName))
            {
                throw new ArgumentException("AddPropertyChangeEvents accepts only BindEventHandlers with set TargetPropertyName");
            }

            var listenDependencyProp = BindHelper.LocateDependencyProperty(bindItem.TargetPropertyName, dependencyObject);

            if (listenDependencyProp == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents cannot obtain proper Type of TargetPropertyName = " + bindItem.TargetPropertyName);
            }

            DependencyPropertyDescriptor dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(listenDependencyProp, listenDependencyProp.OwnerType);

            if (dependencyPropertyDescriptor == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents cannot obtain proper Descriptor of TargetPropertyName = " + bindItem.TargetPropertyName);
            }

            var methodInfo = BindHelper.GetMethodInfo(bindItem.Source.GetType(), bindItem.MethodName);

            Type desiredDelegateType = typeof(EventHandler);

            var result = methodInfo.CreateDelegate(desiredDelegateType, bindItem.Source);

            if (result != null)
            {
                dependencyPropertyDescriptor.AddValueChanged(dependencyObject, (EventHandler)result);
            }
        }
Пример #6
0
        /// <summary>
        /// The method which will be called for the attached dependency property when  the new element is added to a fake collection.
        /// </summary>
        /// <param name="dependencyObject">The target FrameworkElement.</param>
        /// <param name="item">The new object to add.</param>
        public static void ProcessAddPropertyChangeEventItems(DependencyObject dependencyObject, object item)
        {
            if ((item == null) || (dependencyObject == null))
            {
                return;
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }

            BindEventHandlerBase bindItem = item as BindEventHandlerBase;

            if (bindItem == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents accepts only BindEventHandlers Type instances ");
            }

            if (String.IsNullOrEmpty(bindItem.TargetPropertyName))
            {
                throw new ArgumentException("AddPropertyChangeEvents accepts only BindEventHandlers with set TargetPropertyName");
            }

            var listenDependencyProp = BindHelper.LocateDependencyProperty(bindItem.TargetPropertyName, dependencyObject);

            if (listenDependencyProp == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents cannot obtain proper Type of TargetPropertyName = " + bindItem.TargetPropertyName);
            }

            DependencyPropertyDescriptor dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(listenDependencyProp, listenDependencyProp.OwnerType);

            if (dependencyPropertyDescriptor == null)
            {
                throw new ArgumentException("AddPropertyChangeEvents cannot obtain proper Descriptor of TargetPropertyName = " + bindItem.TargetPropertyName);
            }

            var evInfo = BindHelper.GetEventInfo(typeof(BindXAML), "_localTypeStub");

            ProvideValueTarget provideValueTarget = new ProvideValueTarget(dependencyObject, evInfo);
            ServiceProvider    serviceProvider    = new ServiceProvider(provideValueTarget);
            var result = bindItem.ProvideValue(serviceProvider);

            if (result != null)
            {
                dependencyPropertyDescriptor.AddValueChanged(dependencyObject, (EventHandler)result);
            }
        }
Пример #7
0
        /// <summary>
        /// Provides set a property - (XAML attached property set pattern.)
        /// </summary>
        /// <param name="dependencyObject">The target FrameworkElement.</param>
        /// <param name="item">The item  object to add.</param>
        private static void ProcessSetPropertyItem(DependencyObject dependencyObject, object item)
        {
            if ((item == null) || (dependencyObject == null))
            {
                return;
            }

            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }

            var    bindItemPropInf    = item.GetPropertyInfo("TargetPropertyName");
            string targetPropertyName = (string)bindItemPropInf.GetValue(item, null);

            if (String.IsNullOrEmpty(targetPropertyName))
            {
                throw new ArgumentException("AssignToProperties accepts only elements with set 'TargetPropertyName'");
            }

            // CLR property
            PropertyInfo propInfo = dependencyObject.GetPropertyInfo(targetPropertyName);

            // WPF Dependency Property
            DependencyProperty depdInfo = BindHelper.LocateDependencyProperty(targetPropertyName, dependencyObject);

            if ((propInfo == null) && (depdInfo == null))
            {
                throw new ArgumentException("AssignToProperties cannot resolve 'TargetPropertyName' = " + targetPropertyName);
            }

            ProvideValueTarget provideValueTarget;
            var methodInfo = item.GetMethodInfo("ProvideValue");

            if (methodInfo == null)
            {
                throw new ArgumentException("AssignToProperties cannot resolve ProvideValue(...) Method");
            }
            if (propInfo != null)
            {
                // CLR
                provideValueTarget = new ProvideValueTarget(dependencyObject, propInfo);
                ServiceProvider serviceProvider = new ServiceProvider(provideValueTarget);
                var             result          = methodInfo.Invoke(item, new object[] { serviceProvider });
                propInfo.SetValue(dependencyObject, result, null);
            }
            else
            {
                // WPF
                provideValueTarget = new ProvideValueTarget(dependencyObject, depdInfo);
                ServiceProvider serviceProvider = new ServiceProvider(provideValueTarget);
                var             result          = methodInfo.Invoke(item, new object[] { serviceProvider });
                dependencyObject.SetValue(depdInfo, result);
            }
        }
Пример #8
0
        /// <summary>
        /// Sets a new value for the attached dependency property.
        /// Case WPF  - if an added object implements the MarkupExtension abstract class, the ProvideValue method will be called. The result
        /// of this method will be passed as a value. Otherwise the object instance will be passed as a value.
        /// Case WinRt - Nothing will be called and an object instance will be passed as a value.
        /// </summary>
        /// <param name="dependencyObject">The target dependency object for an attached property.</param>
        /// <param name="value">The value to set for a attached dependency property.</param>
        /// <returns>WinRt should return a result an object for the attached property set type operation.</returns>
        public static void SetBindToCommand(DependencyObject dependencyObject, object value)
        {
            if (BindHelper.IsInDesignModeStatic)
            {
                // Cannot correctly set in the design mode.
                return;
            }
#endif

            // For WPF, the BindCommandBase class returns the object instance of  the BindCommandBase class when the method ProvideValue has been called.
            object result           = null;
            var    frameworkElement = dependencyObject as FrameworkElement;
            var    commandBase      = value as BindCommandBase;
            if (commandBase == null)
            {
                throw new ArgumentException("BindToCommand accepts only BindCommand type objects");
            }
            string targetPropertyName = "Command";
            if (frameworkElement != null)
            {
                // CLR property
                PropertyInfo propInfo = dependencyObject.GetPropertyInfo(targetPropertyName);

                // WPF Dependency Property
                DependencyProperty depdInfo = BindHelper.LocateDependencyProperty(targetPropertyName, dependencyObject);

                if ((propInfo == null) && (depdInfo == null))
                {
                    throw new ArgumentException("AssignToProperties cannot resolve TargetPropertyName = " + targetPropertyName);
                }

                ProvideValueTarget provideValueTarget;
                if (propInfo != null)
                {
                    // CLR
                    provideValueTarget = new ProvideValueTarget(frameworkElement, propInfo);
                    ServiceProvider serviceProvider = new ServiceProvider(provideValueTarget);
                    // For WPF we have to call in the second time in order to get a correct value.
                    result = commandBase.ProvideValue(serviceProvider);
                    propInfo.SetValue(frameworkElement, result, null);
                }
                else
                {
                    // WPF
                    provideValueTarget = new ProvideValueTarget(frameworkElement, depdInfo);
                    ServiceProvider serviceProvider = new ServiceProvider(provideValueTarget);
                    result = commandBase.ProvideValue(serviceProvider);
                    dependencyObject.SetValue(depdInfo, result);
                }
            }
#if WINDOWS_UWP
            return(result);
#endif
        }
        void FillCandidateNameRanks(WiringCandidatePair candidateVmType)
        {
            var efffectiveAliasSplit   = BindHelper.SplitNameByCase(candidateVmType.WiringName);
            var desiredXClassNameSplit = BindHelper.SplitNameByCase(candidateVmType.DesiredXCLassName);
            var desiredXNameSplit      = BindHelper.SplitNameByCase(candidateVmType.DesiredXName);

            candidateVmType.WiringNameRank        = efffectiveAliasSplit.Count;
            candidateVmType.DesiredXClassNameRank = desiredXClassNameSplit.Count;
            candidateVmType.DesiredXNameRank      = desiredXNameSplit.Count;
            candidateVmType.DesiredXClassNameMatchToWiringNameRank = BindHelper.CalculateMatchingRank(desiredXClassNameSplit, efffectiveAliasSplit);
            candidateVmType.DesiredXNameMatchToWiringNameRank      = BindHelper.CalculateMatchingRank(desiredXNameSplit, efffectiveAliasSplit);
        }
Пример #10
0
        /// <summary>
        /// Creates the instance of the class and returns the <see cref="RoutedEventHandler"/> type delegate to the proxy method.
        /// </summary>
        /// <param name="desiredDelegateType">Desired type of a delegate.</param>
        /// <param name="methodName">The method name.</param>
        /// <param name="propertyName">Property type.</param>
        /// <returns>Delegate of the <see cref="RoutedEventHandler"/> type.</returns>
        public static object CreateProxyDelegate(Type desiredDelegateType, string methodName, string propertyName = null)
        {
            var  delInvoke    = desiredDelegateType.GetMethodInfo("Invoke");
            var  parms        = delInvoke.GetParameters();
            Type typeGenerate = parms[1].ParameterType;
            Type classType    = typeof(DataContextProxyRoutedEventHandlerGen <>);

            classType = classType.MakeGenericType(typeGenerate);
            var inst = Activator.CreateInstance(classType, methodName, propertyName);

            return(BindHelper.EventHandlerDelegateFromMethod("RoutedEventHandlerProxy", inst, desiredDelegateType));
        }
Пример #11
0
        /// <summary>
        /// Get a source object for binding, an object matching the key in resource dictionaries.
        /// </summary>
        /// <param name="serviceProvider">Object that can provide services for the markup extension.</param>
        /// <returns>Reference to a source object.</returns>
        protected override object ObtainSourceObject(IServiceProvider serviceProvider)
        {
#if WINDOWS_UWP
            // ReSharper disable SuggestUseVarKeywordEvident
            IProvideValueTarget service = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            // ReSharper restore SuggestUseVarKeywordEvident
            // For WinRT we provide a valid targets through BindXAML class.
            object obj = BindHelper.LocateResource(service.TargetObject as FrameworkElement, ResourceKey);
            return(obj);
#else
            // For WPF we have got a StaticResourceExtension to get a Resource
            return(ResourceSource.ProvideValue(serviceProvider));
#endif
        }
Пример #12
0
        void LateBiningOfCommandInterface(object obj, RoutedEventArgs args)
#endif
        {
            object dataContext;

            if (DeepScanAllTrees)
            {
                dataContext = BindHelper.LocateValidDependencyPropertyByAllTrees(TargetObject as DependencyObject, FrameworkElement.DataContextProperty, ExecuteMethodName, ExecutePropertyName);
            }
            else
            {
                dataContext = BindHelper.LocateValidDependencyPropertyByAllTrees(TargetObject as DependencyObject, FrameworkElement.DataContextProperty);
            }

            var frameworkElement = TargetObject as FrameworkElement;

            if (frameworkElement == null)
            {
                return;
            }
            // Remove handler back

#if !WINDOWS_UWP
            DependencyPropertyDescriptor dppDescr = DependencyPropertyDescriptor.FromProperty(FrameworkElement.DataContextProperty, FrameworkElement.DataContextProperty.OwnerType);
            dppDescr.RemoveValueChanged(frameworkElement, LateBiningOfCommandInterface);
#else
            frameworkElement.Loaded -= LateBiningOfCommandInterface;
#endif

            if (dataContext != null)
            {
                var replaceCommand = ResolvePropertyValues(dataContext);

#if !WINDOWS_UWP
                if (TargetProperty is DependencyProperty)
                {
                    frameworkElement.SetValue((DependencyProperty)TargetProperty, replaceCommand);
                }
#else
                if (TargetProperty as PropertyInfo != null)
                {
                    ((PropertyInfo)TargetProperty).SetValue(TargetObject, replaceCommand);
                }
#endif
            }
        }
Пример #13
0
        /// <summary>
        /// Represents the proxy method that will handle various routed events that do not
        /// have specific event data beyond the data that is common for all routed events.
        /// </summary>
        /// <param name="sender">The object which is the originator of the event.</param>
        /// <param name="e">The event data.</param>
        public void RoutedEventHandlerProxy(object sender, T e)
        {
            if ((_handler == null) && (!_errorInHandlerSetup))
            {
                // Try to get a proper handler
                var element = sender as DependencyObject;
                if (element != null)
                {
                    var sourceBaseProvided = BindHelper.LocateValidDependencyPropertyByAllTrees(element, FrameworkElement.DataContextProperty, _methodName, _propertyName);
                    if (sourceBaseProvided != null)
                    {
                        try
                        {
                            if (!string.IsNullOrEmpty(_methodName))
                            {
                                _handler = (ProxyEventHandler)BindHelper.EventHandlerDelegateFromMethod(_methodName, sourceBaseProvided, typeof(ProxyEventHandler));
                            }
                            if (!string.IsNullOrEmpty(_propertyName))
                            {
                                _handler = (ProxyEventHandler)BindHelper.EventHandlerDelegateFromProperty(_propertyName, sourceBaseProvided, typeof(ProxyEventHandler));
                            }
                        }
#if DEBUG
                        catch (Exception ex)
                        {
                            // Should cause an exception if binding was not resolved.
                            Debug.WriteLine($"Cannot create delegate: {_methodName}|{_propertyName} for {sourceBaseProvided} Exception: {ex.Message}");
#else
                        catch
                        {
#endif
                            _errorInHandlerSetup = true;
                        }
                    }
                }
            }
            if (_handler != null)
            {
                _handler(sender, e);
            }
        }
Пример #14
0
        /// <summary>
        /// Constructs the attribute for View model mapping.
        /// </summary>
        /// <param name="commaSeparatedAliases">The comma separated aliases of the candidate type name.</param>
        public ViewModelClassAliasAttribute(string commaSeparatedAliases)
        {
            var targets = commaSeparatedAliases.Split(',');

            foreach (var item in targets)
            {
                var name = item.TrimStart().TrimEnd();
                if (!string.IsNullOrEmpty(name))
                {
                    if (BindHelper.ValidateElementName(name))
                    {
                        _aliases.Add(name);
                    }
                }
            }
#if DEBUG
            if (_aliases.Count == 0)
            {
                throw new InvalidOperationException("Names was not defined.");
            }
#endif
        }
Пример #15
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));
        }
        object ProcessAutoWiringToViewModel(FrameworkElement frameworkElement)
        {
            List <XClassTypeNameElement> parentXClassList = BindHelper.FindNonSystemParentClassNames(frameworkElement, UseTheFirstOne);

            //collect in the here below all possible candidates
            var    viewModelCandidates = new List <WiringCandidatePair>();
            string desiredVmNameSpace  = string.Empty;

            foreach (XClassTypeNameElement parentXClass in parentXClassList)
            {
                // Split a full type name in the sections
                var parentFullClassNameSections = new List <string>(parentXClass.FullxClassTypeName.Split('.'));

                if ((!string.IsNullOrEmpty(ViewsNamespaceSuffixSection)) && (!string.IsNullOrEmpty(ViewModelsNamespaceSuffixSection)))
                {
                    if (parentFullClassNameSections.Count >= 3)
                    {
                        {
                            // if a name space suffix section contains a "Views"(default see prop. ViewsNameSpaceSuffixSection),
                            // this section will be replaced on "ViewModels"(default see prop.ViewModelsNameSpaceSuffixSection)
                            if (parentFullClassNameSections[parentFullClassNameSections.Count - 2].Contains(ViewsNamespaceSuffixSection))
                            {
                                parentFullClassNameSections[parentFullClassNameSections.Count - 2] = ViewModelsNamespaceSuffixSection;
                            }
                        }
                    }
                    else
                    {
                        // If there is no a suffix section, i.e a name space  has only one or two, the suffix section "ViewModels"(default see prop.ViewModelsNameSpaceSuffixSection)
                        // will be added.
                        parentFullClassNameSections.Insert(parentFullClassNameSections.Count - 1, ViewModelsNamespaceSuffixSection);
                    }
                }

                // Form a desired View Model  namespace for a type.
                desiredVmNameSpace = string.Join(".", parentFullClassNameSections.ToArray(), 0, parentFullClassNameSections.Count - 1);
                if (!string.IsNullOrEmpty(ViewModelNamespaceOverwrite))
                {
                    desiredVmNameSpace = ViewModelNamespaceOverwrite;
                }

                string desiredVmXName      = string.Empty;
                string desiredVmXClassName = string.Empty;

                if (!string.IsNullOrEmpty(ViewModelNameOverwrite))
                {
                    // Overwrite the names i.e. x:Class x:Name
                    desiredVmXClassName = ViewModelNameOverwrite;
                }
                else
                {
                    if ((!string.IsNullOrEmpty(OldViewNamePart)) && (!string.IsNullOrEmpty(NewViewModelNamePart)))
                    {
                        // Form a desired View Model name (i.e. class name) for a type.
                        // If a type name (i.e. class name) contains "View"(default see prop."OldNamePart"), it will be replaced on "ViewModel"(default see prop."NewNamePart").
                        desiredVmXClassName = parentFullClassNameSections[parentFullClassNameSections.Count - 1];
                        if (!desiredVmXClassName.Contains(NewViewModelNamePart))
                        {
                            desiredVmXClassName = desiredVmXClassName.Replace(OldViewNamePart, NewViewModelNamePart);
                        }
                        if (!string.IsNullOrEmpty(parentXClass.XNameForXClass))
                        {
                            desiredVmXName = parentXClass.XNameForXClass;
                            if (!desiredVmXName.Contains(NewViewModelNamePart))
                            {
                                desiredVmXName = desiredVmXName.Replace(OldViewNamePart, NewViewModelNamePart);
                            }
                        }
                    }
                }

#if DEBUG
                if (!string.IsNullOrEmpty(desiredVmXClassName))
                {
                    Debug.WriteLine("#INFO#-A-W-V-M# Desired x:Class, Type: {0}.{1}", desiredVmNameSpace, desiredVmXClassName);
                }

                if (!string.IsNullOrEmpty(desiredVmXName))
                {
                    Debug.WriteLine("#INFO#-A-W-V-M# Desired x:Name,  Type: {0}.{1} ", desiredVmNameSpace, desiredVmXName);
                }
#endif
                var candidateTypes = BindHelper.ResolveTypesByNameSpace(desiredVmNameSpace);

                foreach (Type item in candidateTypes)
                {
                    WiringCandidatePair candidateVmType = new WiringCandidatePair();
                    candidateVmType.XClass            = parentXClass;
                    candidateVmType.WiringType        = item;
                    candidateVmType.WiringName        = item.Name;
                    candidateVmType.DesiredXCLassName = desiredVmXClassName;
                    candidateVmType.DesiredXName      = desiredVmXName;
                    viewModelCandidates.Add(candidateVmType);
                    FillCandidateNameRanks(candidateVmType);
                    // Process attributes for a class
#if !WINDOWS_UWP
                    var attribV = Attribute.GetCustomAttributes(item, typeof(ViewModelClassAliasAttribute));
#else
                    var attribV = item.GetTypeInfo().GetCustomAttributes(typeof(ViewModelClassAliasAttribute));
#endif
                    if (attribV != null)
                    {
                        foreach (Attribute att in attribV)
                        {
                            var list = ((ViewModelClassAliasAttribute)att).Aliases;
                            foreach (var alias in list)
                            {
                                candidateVmType                   = new WiringCandidatePair();
                                candidateVmType.XClass            = parentXClass;
                                candidateVmType.WiringType        = item;
                                candidateVmType.WiringName        = alias;
                                candidateVmType.DesiredXCLassName = desiredVmXClassName;
                                candidateVmType.DesiredXName      = desiredVmXName;
                                viewModelCandidates.Add(candidateVmType);
                                FillCandidateNameRanks(candidateVmType);
                            }
                        }
                    }
                }
            }

            WiringCandidatePair locatedItem = null;
            if (viewModelCandidates.Count == 0)
            {
                Debug.WriteLine("#ERROR#-A-W-V-M# Cannot locate candidate Types in namespace: " + desiredVmNameSpace);
                return(null);
            }

            List <WiringCandidatePair> wiringTemp;

            if (locatedItem == null)
            {
                wiringTemp = viewModelCandidates.Where(itm => itm.IsXNameMatch).ToList();
                if (wiringTemp.Count > 0)
                {
                    locatedItem = wiringTemp[0];
                }
            }

            if (locatedItem == null)
            {
                wiringTemp = viewModelCandidates.Where(itm => itm.IsXClassNameMatch).ToList();
                if (wiringTemp.Count > 0)
                {
                    locatedItem = wiringTemp[0];
                }
            }

            if ((locatedItem == null) && (UseMaxNameSubMatch))
            {
                //if (locatedItem == null)
                {
                    wiringTemp = viewModelCandidates.Where(itm => itm.IsXNameSubMatch).ToList();
                    if (wiringTemp.Count > 0)
                    {
                        locatedItem = wiringTemp[0];
                    }
                }

                if (locatedItem == null)
                {
                    wiringTemp = viewModelCandidates.Where(itm => itm.IsXClassNameSubMatch).ToList();
                    if (wiringTemp.Count > 0)
                    {
                        locatedItem = wiringTemp[0];
                    }
                }
            }

            if (locatedItem == null)
            {
                Debug.WriteLine("#ERROR#-A-W-V-M# Cannot locate proper candidate Types in: " + desiredVmNameSpace);
                return(null);
            }
#if DEBUG
            else
            {
                Debug.WriteLine("#INFO#-A-W-V-M# Located Type: " + locatedItem.WiringFullName);
            }
#endif
            object resolvedObject = null;
            // Resolve over the IOC container - the first.
            if (ResolveIocContainer && BindHelper.IsIocContainerActive)
            {
                if (ServiceProvider != null)
                {
                    try { resolvedObject = ServiceProvider.GetService(locatedItem.WiringType); } catch { }
#if DEBUG
                    if (resolvedObject != null)
                    {
                        Debug.WriteLine("#INFO#-A-W-V-M# Resolved with IoC,  GetInstance(typeof({0}))", new object[] { locatedItem.WiringFullName });
                    }
#endif
                }
                else
                {
                    try { resolvedObject = Activator.CreateInstance(locatedItem.WiringType); } catch { }
#if DEBUG
                    if (resolvedObject != null)
                    {
                        Debug.WriteLine("#INFO#-A-W-V-M# Resolved with Activator Type: " + locatedItem.WiringFullName);
                    }
#endif
                }
            }


            // Resolve over the resources container the second.
            if ((ResolveResources) && (resolvedObject == null))
            {
                if (!string.IsNullOrEmpty(locatedItem.DesiredXName))
                {
                    resolvedObject = BindHelper.LocateResource(frameworkElement, locatedItem.DesiredXName);
#if DEBUG
                    if (resolvedObject != null)
                    {
                        Debug.WriteLine("#INFO#-A-W-V-M# Resolved with WPF Resource Key: " + locatedItem.DesiredXName);
                    }
#endif
                }
                resolvedObject = BindHelper.LocateResource(frameworkElement, locatedItem.WiringTypeName);
#if DEBUG
                if (resolvedObject != null)
                {
                    Debug.WriteLine("#INFO#-A-W-V-M# Resolved with WPF Resource Key: " + locatedItem.WiringTypeName);
                }
#endif
                if (resolvedObject == null)
                {
                    resolvedObject = BindHelper.LocateResource(frameworkElement, locatedItem.WiringFullName);
#if DEBUG
                    if (resolvedObject != null)
                    {
                        Debug.WriteLine("#INFO#-A-W-V-M# Resolved with WPF Resource Key: " + locatedItem.WiringFullName);
                    }
#endif
                }
                if (resolvedObject == null)
                {
                    resolvedObject = BindHelper.LocateResource(frameworkElement, locatedItem.WiringType);
#if DEBUG
                    if (resolvedObject != null)
                    {
                        Debug.WriteLine("#INFO#-A-W-V-M# Resolved with WPF Resource Key type of : " + locatedItem.WiringFullName);
                    }
#endif
                }
            }


            // Create instance over the real type the third.
            if ((ResolveCreateInstance) && (resolvedObject == null))
            {
                try { resolvedObject = Activator.CreateInstance(locatedItem.WiringType); }
                catch
                {
                    // ignored
                }
#if DEBUG
                if (resolvedObject != null)
                {
                    Debug.WriteLine("#INFO#-A-W-V-M# Resolved with Activator Type: " + locatedItem.WiringFullName);
                }
#endif
            }

            if (resolvedObject != null)
            {
                // setup resolved object to property
                DependencyProperty target = BindHelper.LocateDependencyProperty(TargetPropertyName, frameworkElement);
                if (target != null)
                {
                    frameworkElement.SetValue(target, resolvedObject);
                    // store auto resolved ViewModel into
                    BindXAML.SetAutoWiredViewModel(frameworkElement, resolvedObject);
                }
            }

#if DEBUG
            if (resolvedObject == null)
            {
                Debug.WriteLine("#ERROR#-A-W-V-M# Cannot Resolve Type: " + locatedItem.WiringFullName);
            }
#endif
            return(resolvedObject);
        }
        /// <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);
        }
Пример #18
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);
        }
Пример #19
0
        /// <summary>
        /// Locate properties and fields that marked with attribute <see cref="AppendViewModelAttribute"/>
        /// </summary>
        /// <param name="obj">Object to scan</param>
        /// <returns>Returns the list of located objects.</returns>
        static public List <Tuple <Type, object> > LocateAppendedViewModels(object obj)
        {
            List <Tuple <Type, object> > res = new List <Tuple <Type, object> >();
            var lookUpObject = obj;
            var lookUpType   = obj.GetType();

#if WINDOWS_UWP
            IEnumerable <FieldInfo> info;
#else
            FieldInfo[] info;
#endif
#if WINDOWS_UWP
            info = lookUpType.GetTypeInfo().DeclaredFields;
#else
            info = lookUpType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
#endif
            foreach (var item in info)
            {
#if !WINDOWS_UWP
                var attribR = Attribute.GetCustomAttributes(item, typeof(AppendViewModelAttribute));
                var fType   = item.FieldType;
#else
                var attribR = item.GetCustomAttributes(typeof(AppendViewModelAttribute));
                var fType   = item.FieldType.GetTypeInfo();
#endif

                if (!fType.IsValueType && !BindHelper.CheckKnownTypePrefix(fType.FullName))
                {
                    foreach (Attribute att in attribR)
                    {
                        object value = item.GetValue(lookUpObject);
                        if (value != null)
                        {
                            res.Add(new Tuple <Type, object>(item.FieldType, value));
                        }
                    }
                }
            }

#if WINDOWS_UWP
            IEnumerable <PropertyInfo> propertyInfos;
            propertyInfos = lookUpType.GetTypeInfo().DeclaredProperties;
#else
            PropertyInfo[] propertyInfos;
            propertyInfos = lookUpType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
#endif
            foreach (var item in propertyInfos)
            {
#if !WINDOWS_UWP
                var attribR = Attribute.GetCustomAttributes(item, typeof(AppendViewModelAttribute));
                var fType   = item.PropertyType;
#else
                var attribR = item.GetCustomAttributes(typeof(AppendViewModelAttribute));
                var fType   = item.PropertyType.GetTypeInfo();
#endif

                if (!fType.IsValueType && !BindHelper.CheckKnownTypePrefix(fType.FullName))
                {
                    foreach (Attribute att in attribR)
                    {
                        object value = item.GetValue(lookUpObject, null);
                        if (value != null)
                        {
                            res.Add(new Tuple <Type, object>(item.PropertyType, value));
                        }
                    }
                }
            }

            return(res);
        }
Пример #20
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);
        }
Пример #21
0
        /// <summary>
        /// Returns an object that should be set on the property where this extension is applied.
        /// </summary>
        /// <param name="serviceProvider">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>
        /// <exception cref="System.InvalidOperationException">serviceProvider was null, or failed to
        /// implement a required service.</exception>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException("serviceProvider");
            }

            if (_serviceType == null)
            {
                // ReSharper disable NotResolvedInText
                throw new ArgumentNullException("IocBinding - ServiceType cannot be null.");
                // ReSharper restore NotResolvedInText
            }


            Type typeToResolve;

            // ReSharper disable CanBeReplacedWithTryCastAndCheckForNull
            if (_serviceType is Type)
            // ReSharper restore CanBeReplacedWithTryCastAndCheckForNull
            {
                typeToResolve = (Type)_serviceType;
            }
            // ReSharper disable CanBeReplacedWithTryCastAndCheckForNull
            else if (_serviceType is string)
            // ReSharper restore CanBeReplacedWithTryCastAndCheckForNull
            {
#if !WINDOWS_UWP
                // ReSharper disable SuggestUseVarKeywordEvident
                IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
                // ReSharper restore SuggestUseVarKeywordEvident

                typeToResolve = BindHelper.ResolveTypeByName((string)_serviceType);

                if ((service != null) && (typeToResolve == null))
                {
                    typeToResolve = service.Resolve((string)_serviceType);
                }
#else
                typeToResolve = BindHelper.ResolveTypeByName((string)_serviceType);
#endif

                if (typeToResolve == null)
                {
                    throw new InvalidOperationException("IocBinding invalid  cannot resolve type - " + (string)_serviceType);
                }
            }
            else
            {
                // ReSharper disable NotResolvedInText
                throw new ArgumentNullException("IocBinding - ServiceType can be 'Type' or 'String'.");
                // ReSharper restore NotResolvedInText
            }
            if (AutoWireVmDataContext.ServiceProvider != null)
            {
                try { ResolvedResult = AutoWireVmDataContext.ServiceProvider.GetService(typeToResolve); } catch { }
                if (ResolvedResult == null)
                {
                    try { ResolvedResult = Activator.CreateInstance(typeToResolve); } catch { }
                }
            }

#if !WINDOWS_UWP
            // ReSharper disable SuggestUseVarKeywordEvident
            IProvideValueTarget valueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            // ReSharper restore SuggestUseVarKeywordEvident

            //Attached collection support
            if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetObject is FakeCollection) && (valueTarget.TargetProperty == null))
            {
                return(this);
            }

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

            //if ((valueTarget != null) && (valueTarget.TargetObject != null) && (valueTarget.TargetProperty != null) && (valueTarget.TargetProperty as MethodInfo != null))
            //{
            //    // Support for a single attached property for WPF
            //    // XAML WinRt doesn't call ProvideValue() but WPF always does call ProvideValue()
            //    // In this case if use the single attached property we have to demonstrate
            //    return this; // That should be done like that
            //}
#endif
            if (!String.IsNullOrEmpty(PropertyName))
            {
                if (ResolvedResult != null)
                {
                    var info = ResolvedResult.GetPropertyInfo(PropertyName);
                    if (info == null)
                    {
                        throw new ArgumentException("IocBinding - cannot resolve 'TargetPropertyName' property  " + PropertyName);
                    }
                    ResolvedResult = info.GetValue(ResolvedResult, null);
                }
            }
            return(ResolvedResult);
        }