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