Пример #1
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);
            }
        }
Пример #2
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);
            }
        }
Пример #3
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);
            }
        }
Пример #4
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
        }
        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);
        }