예제 #1
0
        internal bool INTERNAL_ForceValidateOnNextSetValue = false; //This boolean is set to true in OnAttached to force Validation at the next UpdateSourceObject. Its purpose is to force the Validation only once to avoid hindering performances.

        internal void OnAttached(DependencyObject target)
        {
            if (IsAttached)
            {
                return;
            }

            IsAttached = true;
            //get the DataContextProperty.
            string             dataContextPropertyName = "DataContext";
            Type               type = target.GetType();
            DependencyProperty dataContextDependencyProperty = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(type, dataContextPropertyName);

            if (dataContextDependencyProperty != null)
            {
                object dataContext = target.GetValue(dataContextDependencyProperty);
                this.OnDataContextChanged(dataContext);
            }

            var source = FindSource();

            PropertyPathWalker.Update(source); //FindSource should find the source now. Otherwise, the PropertyPathNodes shoud do the work (their properties will change when the source will become available)

            //Listen to changes on the Target if the Binding is TwoWay:
            if (ParentBinding.Mode == BindingMode.TwoWay)
            {
                PropertyListener = INTERNAL_PropertyStore.ListenToChanged(Target, Property, UpdateSourceCallback);

                //If the user wants to force the Validation of the value when the element is added to the Visual tree, we set a boolean to do it as soon as possible:
                if (ParentBinding.ValidatesOnExceptions && ParentBinding.ValidatesOnLoad)
                {
                    INTERNAL_ForceValidateOnNextSetValue = true;
                }
            }
        }
예제 #2
0
        internal override void OnSourceChanged(object oldvalue, object newValue)
        {
            DependencyObject oldSource = oldvalue as DependencyObject;
            DependencyObject newSource = newValue as DependencyObject;

            var listener = _dependencyPropertyListener;

            if (listener != null)
            {
                listener.Detach();
                _dependencyPropertyListener = listener = null;
            }

            DependencyProperty = null;
            PropertyInfo       = null;
            FieldInfo          = null;
            if (Source == null)
            {
                return;
            }

            if (newSource != null)
            {
                if (!BindsDirectlyToSource)
                {
                    DependencyProperty dependencyProperty;
                    if (_propertyName == "DataContext")
                    {
                        dependencyProperty = FrameworkElement.DataContextProperty;
                    }
                    else
                    {
                        Type type = Source.GetType();
                        dependencyProperty = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(type, _propertyName);
                    }

                    if (dependencyProperty != null)
                    {
                        this.DependencyProperty          = dependencyProperty;
                        this._dependencyPropertyListener = listener = INTERNAL_PropertyStore.ListenToChanged(newSource, dependencyProperty, this.OnPropertyChanged);
                    }
                } //else (if there is no path), we don't need a listener because changing the source will directly call this method.
            }

            //todo: support attached DependencyProperties
            if (DependencyProperty == null)// || !this.DependencyProperty.IsAttached)
            {
                if (!BindsDirectlyToSource)
                {
                    Type sourceType = Source.GetType();
                    this.PropertyInfo = sourceType.GetProperty(_propertyName);
                    if (this.PropertyInfo == null)
                    {
                        // Try in case it is a simple field instead of a property:
                        this.FieldInfo = sourceType.GetField(_propertyName);
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Registers a dependency property with the specified property name, property type, owner type, and property metadata.
        /// </summary>
        /// <param name="name">The property name.</param>
        /// <param name="propertyType">The type of the property.</param>
        /// <param name="ownerType">The type of the property's owner.</param>
        /// <param name="typeMetadata">The property metadata.</param>
        /// <returns>The DependencyProperty.</returns>
        public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
        {
#if PERFSTAT
            var t = Performance.now();
#endif
            PropertyMetadata defaultMetadata = typeMetadata;
            if (defaultMetadata == null)
            {
                //Create metadata if not set
                defaultMetadata = new PropertyMetadata();
            }
            // Make sure typeMetadata default value is valid.
            EnsureDefaultValue(defaultMetadata, propertyType, name, ownerType);

            defaultMetadata.Seal();

            var newDependencyProperty = new DependencyProperty()
            {
                Name             = name,
                PropertyType     = propertyType,
                OwnerType        = ownerType,
                _defaultMetadata = defaultMetadata
            };

            // Add the dependency property to the list of all the dependency properties of the object:
            INTERNAL_TypeToDependencyProperties.Add(ownerType, newDependencyProperty);

            // Add the dependency property to the list that is used to know whether to always call "PropertyChanged" when the UI element is loaded into the Visual Tree:
            if (typeMetadata != null && typeMetadata.CallPropertyChangedWhenLoadedIntoVisualTree == WhenToCallPropertyChangedEnum.Always)
            {
                INTERNAL_TypeToDependencyPropertiesThatRequirePropertyChanged.Add(ownerType, newDependencyProperty);
            }

            //Add the dependencyProperty's name to the dictionary that allows to get the dependencyProperty from its name:
            Dictionary <string, DependencyProperty> stringsToDependencyProperties = INTERNAL_TypeToStringsToDependencyProperties.GetDictionaryForType(ownerType);
            if (stringsToDependencyProperties.ContainsKey(name))
            {
#if !MIGRATION
                // THE FOLLOWING CHECK IS DISABLED IN THE SILVERLIGHT COMPATIBLE VERSION
                // BECAUSE IT APPEARS THAT SILVERLIGHT IS TOLERANT TO DECLARING TWICE
                // THE SAME DEPENDENCY PROPERTY OR ATTACHED PROPERTY. FOR AN EXAMPLE OF
                // USE, SEE THE CLASS "RatingsView" IN THE CLIENT APPLICATION "STAR".
                if (stringsToDependencyProperties[name] != null)
                {
                    throw new Exception("Cannot register multiple properties with the same PropertyName");
                }
#endif
                stringsToDependencyProperties[name] = newDependencyProperty;
            }
            else
            {
                stringsToDependencyProperties.Add(name, newDependencyProperty);
            }
#if PERFSTAT
            Performance.Counter("DependencyProperty.Register", t);
#endif
            return(newDependencyProperty);
        }
예제 #4
0
        internal virtual void OnAttached(DependencyObject target)
        {
            this.IsAttached = true;
            //get the DataContextProperty.
            string             dataContextPropertyName = "DataContext";
            Type               type = target.GetType();
            DependencyProperty dataContextDependencyProperty = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(type, dataContextPropertyName);

            if (dataContextDependencyProperty != null)
            {
                object dataContext = target.GetValue(dataContextDependencyProperty);
                this.OnDataContextChanged(dataContext);
            }
        }
예제 #5
0
        public override object ProvideValue(ServiceProvider serviceProvider)
#endif
        {
            var provider = (ServiceProvider)serviceProvider.GetService(typeof(ServiceProvider));

            if (provider != null)
            {
                var dp = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(
                    provider.TargetObject?.GetType(), Path);
                var source = provider.TargetObject as Control;

                if (dp != null && source != null)
                {
                    return(new TemplateBindingExpression(source, dp));
                }
            }

            return(DependencyProperty.UnsetValue);
        }
        internal override void OnSourceChanged(object oldValue, object newValue)
        {
            if (oldValue is INotifyPropertyChanged inpc)
            {
                inpc.PropertyChanged -= new PropertyChangedEventHandler(OnSourcePropertyChanged);
            }

            IPropertyChangedListener listener = _dpListener;

            if (listener != null)
            {
                _dpListener = null;
                listener.Detach();
            }

            _dp    = null;
            _prop  = null;
            _field = null;

            if (Source == null)
            {
                return;
            }

            if (_bindsDirectlyToSource)
            {
                return;
            }

            inpc = newValue as INotifyPropertyChanged;
            if (inpc != null)
            {
                inpc.PropertyChanged += new PropertyChangedEventHandler(OnSourcePropertyChanged);
            }

            if (newValue is DependencyObject sourceDO)
            {
                Type type = _resolvedType ?? Source.GetType();

                DependencyProperty dependencyProperty = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(type, _propertyName);

                if (dependencyProperty != null)
                {
                    _dp         = dependencyProperty;
                    _dpListener = listener = INTERNAL_PropertyStore.ListenToChanged(sourceDO, dependencyProperty, OnPropertyChanged);
                }
            }

            if (_dp == null)
            {
                Type sourceType = Source.GetType();
                for (Type t = sourceType; t != null; t = t.BaseType)
                {
                    _prop = t.GetProperty(
                        _propertyName,
                        BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly
                        );

                    if (_prop != null)
                    {
                        break;
                    }
                }

                if (_prop == null)
                {
                    // Try in case it is a simple field instead of a property:
                    _field = sourceType.GetField(_propertyName);
                }
            }
        }
예제 #7
0
        internal override void OnSourceChanged(object oldvalue, object newValue)
        {
            DependencyObject oldSource = null;
            DependencyObject newSource = null;

            if (oldvalue is DependencyObject)
            {
                oldSource = (DependencyObject)oldvalue;
            }
            if (newValue is DependencyObject)
            {
                newSource = (DependencyObject)newValue;
            }

            var listener = _dependencyPropertyListener;

            if (listener != null)
            {
                listener.Detach();
                _dependencyPropertyListener = listener = null;
            }

            DependencyProperty = null;
            PropertyInfo       = null;
            FieldInfo          = null;
            if (Source == null)
            {
                return;
            }

            if (newSource != null)
            {
                if (!BindsDirectlyToSource)
                {
                    DependencyProperty dependencyProperty;
                    if (_propertyName == "DataContext") // Note: we handle the special case of the DataContext because the "DataContext" property is defined in the "UIElement" class, and some classes such as "RotateTransform" inherit the DataContext property even though they are not UIElements, so if we looked for the "DataContext" property in the type (and its base types) we wouldn't find it.
                    {
                        dependencyProperty = FrameworkElement.DataContextProperty;
                    }
                    else
                    {
                        Type type = Source.GetType();
                        dependencyProperty = INTERNAL_TypeToStringsToDependencyProperties.GetPropertyInTypeOrItsBaseTypes(type, _propertyName);
                    }

                    if (dependencyProperty != null)
                    {
                        this.DependencyProperty          = dependencyProperty;
                        this._dependencyPropertyListener = listener = INTERNAL_PropertyStore.ListenToChanged(newSource, dependencyProperty, this.OnPropertyChanged);
                    }
                } //else (if there is no path), we don't need a listener because changing the source will directly call this method.
            }

            //todo: support attached DependencyProperties
            if (DependencyProperty == null)// || !this.DependencyProperty.IsAttached)
            {
                if (!BindsDirectlyToSource)
                {
                    Type sourceType = Source.GetType();
                    this.PropertyInfo = sourceType.GetProperty(_propertyName);
                    if (this.PropertyInfo == null)
                    {
                        // Try in case it is a simple field instead of a property:
                        this.FieldInfo = sourceType.GetField(_propertyName);
                    }
                }
            }
        }