/// <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> /// 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> /// 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 }
/// <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 ProcessAddEventItems(DependencyObject dependencyObject, object item) { if ((item == null) || (dependencyObject == null)) { return; } UIElement uiElement = dependencyObject as UIElement; if (uiElement == null) { return; } if (BindHelper.IsInDesignModeStatic) { // Cannot correctly set in the design mode. return; } BindEventHandlerBase bindItem = item as BindEventHandlerBase; if (bindItem == null) { throw new ArgumentException("AddEvents accepts only BindEventHandlers Type instances "); } if (String.IsNullOrEmpty(bindItem.TargetEventName)) { throw new ArgumentException("AddEvents accepts only BindEventHandlers with set TargetEventName"); } var evntInfo = uiElement.GetEventInfo(bindItem.TargetEventName); if (evntInfo == null) { throw new ArgumentException("AddEvents cannot resolve TargetEventName = " + bindItem.TargetEventName); } ProvideValueTarget provideValueTarget = new ProvideValueTarget(uiElement, evntInfo); ServiceProvider serviceProvider = new ServiceProvider(provideValueTarget); var result = bindItem.ProvideValue(serviceProvider); if (result != null) { #if WINDOWS_UWP evntInfo.AddMethod.Invoke(uiElement, new object[] { result }); #else evntInfo.AddEventHandler(uiElement, (Delegate)result); #endif } }