示例#1
0
 internal static void ValidateSources(DependencyObject d, DependencySource[] newSources, Expression expr)
 {
     // Make sure all Sources are owned by the same thread.
     if (newSources != null) 
     {
         Dispatcher dispatcher = d.Dispatcher; 
         for (int i = 0; i < newSources.Length; i++) 
         {
             Dispatcher sourceDispatcher = newSources[i].DependencyObject.Dispatcher; 
             if (sourceDispatcher != dispatcher && !(expr.SupportsUnboundSources && sourceDispatcher == null))
             {
                 throw new ArgumentException(SR.Get(SRID.SourcesMustBeInSameThread));
             } 
         }
     } 
 } 
示例#2
0
        internal static void UpdateSourceDependentLists(DependencyObject d, DependencyProperty dp, DependencySource[] sources, Expression expr, bool add) 
        {
            // Sources already validated to be on the same thread as Dependent (d)

            if (sources != null) 
            {
                // don't hold a reference on the dependent if the expression is doing 
                // the invalidations.  This helps avoid memory leaks (bug 871139) 
                if (expr.ForwardsInvalidations)
                { 
                    d = null;
                    dp = null;
                }
 
                for (int i = 0; i < sources.Length; i++)
                { 
                    DependencySource source = sources[i]; 

                    // A Sealed DependencyObject does not have a Dependents list 
                    // so don't bother updating it (or attempt to add one).

                    Debug.Assert((!source.DependencyObject.IsSealed) ||
                            (DependentListMapField.GetValue(source.DependencyObject) == default(object))); 

                    if (!source.DependencyObject.IsSealed) 
                    { 
                        // Retrieve the DependentListMap for this source
                        // The list of dependents to invalidate is stored using a special negative key 

                        FrugalMap dependentListMap;
                        object value = DependentListMapField.GetValue(source.DependencyObject);
                        if (value != null) 
                        {
                            dependentListMap = (FrugalMap)value; 
                        } 
                        else
                        { 
                            dependentListMap = new FrugalMap();
                        }

                        // Get list of DependentList off of ID map of Source 
                        object dependentListObj = dependentListMap[source.DependencyProperty.GlobalIndex];
                        Debug.Assert(dependentListObj != null, "dependentList should either be unset or non-null"); 
 
                        // Add/Remove new Dependent (this) to Source's list
                        if (add) 
                        {
                            DependentList dependentList;
                            if (dependentListObj == DependencyProperty.UnsetValue)
                            { 
                                dependentListMap[source.DependencyProperty.GlobalIndex] = dependentList = new DependentList();
                            } 
                            else 
                            {
                                dependentList = (DependentList)dependentListObj; 
                            }

                            dependentList.Add(d, dp, expr);
                        } 
                        else
                        { 
                            if (dependentListObj != DependencyProperty.UnsetValue) 
                            {
                                DependentList dependentList = (DependentList)dependentListObj; 

                                dependentList.Remove(d, dp, expr);

                                if (dependentList.IsEmpty) 
                                {
                                    // No more dependencies for this property; reclaim the space if we can. 
                                    dependentListMap[source.DependencyProperty.GlobalIndex] = DependencyProperty.UnsetValue; 
                                }
                            } 
                        }

                        // Set the updated struct back into the source's _localStore.
                        DependentListMapField.SetValue(source.DependencyObject, dependentListMap); 
                    }
                } 
            } 
        }
示例#3
0
        // 
        // Changes the sources of an existing Expression 
        //
        internal static void ChangeExpressionSources(Expression expr, DependencyObject d, DependencyProperty dp, DependencySource[] newSources) 
        {
            if (!expr.ForwardsInvalidations)
            {
                // Get current local value (should be provided Expression) 
                // (No need to go through read local callback, just checking
                // for presence of Expression) 
                EntryIndex entryIndex = d.LookupEntry(dp.GlobalIndex); 

                if (!entryIndex.Found || (d._effectiveValues[entryIndex.Index].LocalValue != expr)) 
                {
                    throw new ArgumentException(SR.Get(SRID.SourceChangeExpressionMismatch));
                }
            } 

            // Get current sources 
            // CALLBACK 
            DependencySource[] currentSources = expr.GetSources();
 
            // Remove old
            if (currentSources != null)
            {
                UpdateSourceDependentLists(d, dp, currentSources, expr, false);  // Remove 
            }
 
            // Add new 
            if (newSources != null)
            { 
                UpdateSourceDependentLists(d, dp, newSources, expr, true);  // Add
            }
        }
示例#4
0
        private EffectiveValueEntry EvaluateExpression( 
            EntryIndex entryIndex,
            DependencyProperty dp, 
            Expression expr,
            PropertyMetadata metadata,
            EffectiveValueEntry oldEntry,
            EffectiveValueEntry newEntry) 
        {
            object value = expr.GetValue(this, dp); 
            bool isDeferredReference = false; 

            if (value != DependencyProperty.UnsetValue && value != Expression.NoValue) 
            {
                isDeferredReference = (value is DeferredReference);
                if (!isDeferredReference && !dp.IsValidValue(value))
                { 
#region EventTracing
#if VERBOSE_PROPERTY_EVENT 
                    if (isDynamicTracing) 
                    {
                        if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
                        {
                            EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYGUID,
                                                                MS.Utility.EventType.EndEvent,
                                                                EventTrace.PROPERTYVALIDATION, 0xFFF ); 
                        }
                    } 
#endif 
#endregion EventTracing
                    throw new InvalidOperationException(SR.Get(SRID.InvalidPropertyValue, value, dp.Name)); 
                }
            }
            else
            { 
                if (value == Expression.NoValue)
                { 
                    // The expression wants to "hide".  First set the 
                    // expression value to NoValue to indicate "hiding".
                    newEntry.SetExpressionValue(Expression.NoValue, expr); 

                    // Next, get the expression value some other way.
                    if (!dp.ReadOnly)
                    { 
                        EvaluateBaseValueCore(dp, metadata, ref newEntry);
                        value = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value; 
                    } 
                    else
                    { 
                        value = DependencyProperty.UnsetValue;
                    }
                }
 
                // if there is still no value, use the default
                if (value == DependencyProperty.UnsetValue) 
                { 
                    value = metadata.GetDefaultValue(this, dp);
                } 
            }

            // Set the expr and its evaluated value into
            // the _effectiveValues cache 
            newEntry.SetExpressionValue(value, expr);
            return newEntry; 
        } 
示例#5
0
		internal void InvalidateLocalBindings ()
		{
			if (expressions == null || expressions.Count == 0)
				return;

			if (invalidatingLocalBindings)
				return;

			invalidatingLocalBindings = true;

			DependencyProperty[] keys = new DependencyProperty [expressions.Keys.Count];
			Expression[] values = new Expression [expressions.Values.Count];

			expressions.Keys.CopyTo (keys, 0);
			expressions.Values.CopyTo (values, 0);

			for (int i = 0; i < keys.Length; i ++) {
				if (values[i] is BindingExpressionBase) {
					BindingExpressionBase beb = (BindingExpressionBase) values[i];
					beb.Invalidate ();
					SetValue (keys[i], beb);
				}
			}

			invalidatingLocalBindings = false;
		}