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