/// <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); } }
/// <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); } }
/// <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); } }
/// <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); }