コード例 #1
0
        static void RenderElementsAndRaiseChangedEventOnAllDependencyProperties(DependencyObject dependencyObject)
        {
            //--------------------------------------------------------------
            // RAISE "PROPERTYCHANGED" FOR ALL THE PROPERTIES THAT HAVE
            // A VALUE THAT HAS BEEN SET, INCLUDING ATTACHED PROPERTIES,
            // AND CALL THE "METHOD TO UPDATE DOM"
            //--------------------------------------------------------------

            // This is used to force a redraw of all the properties that are
            // set on the object (including Attached Properties!). For
            // example, if a Border has a colored background, this is the
            // moment when that color will be applied. Properties that have
            // no value set by the user are not concerned (their default
            // state is rendered elsewhere).

#if PERFSTAT
            var t0 = Performance.now();
#endif
            // we copy the Dictionary so that the foreach doesn't break when
            // we modify a DependencyProperty inside the Changed of another
            // one (which causes it to be added to the Dictionary).
            // we exclude properties where source is set to default because
            // it means they have been set at some point, and unset afterward,
            // so we should not call the PropertyChanged callback.
            var list = dependencyObject.INTERNAL_PropertyStorageDictionary
                       .Where(s => s.Value.BaseValueSourceInternal > BaseValueSourceInternal.Default)
                       .ToList();
#if PERFSTAT
            Performance.Counter("VisualTreeManager: Copy list of properties", t0);
#endif

            foreach (KeyValuePair <DependencyProperty, INTERNAL_PropertyStorage> propertiesAndTheirStorage in list)
            {
                // Read the value:
                DependencyProperty property = propertiesAndTheirStorage.Key;

#if PERFSTAT
                var t1 = Performance.now();
#endif

                PropertyMetadata propertyMetadata = property.GetTypeMetaData(dependencyObject.GetType());

                if (propertyMetadata != null)
                {
                    INTERNAL_PropertyStorage storage = propertiesAndTheirStorage.Value;
                    object value             = null;
                    bool   valueWasRetrieved = false;

                    //--------------------------------------------------
                    // Call "Apply CSS", which uses "GetCSSEquivalent/s"
                    //--------------------------------------------------

                    if (propertyMetadata.GetCSSEquivalent != null || propertyMetadata.GetCSSEquivalents != null)
                    {
                        if (!valueWasRetrieved)
                        {
                            value             = INTERNAL_PropertyStore.GetEffectiveValue(storage);
                            valueWasRetrieved = true;
                        }

                        INTERNAL_PropertyStore.ApplyCssChanges(value, value, propertyMetadata, storage.Owner);
                    }

                    //--------------------------------------------------
                    // Call "MethodToUpdateDom"
                    //--------------------------------------------------
                    if (propertyMetadata.MethodToUpdateDom != null)
                    {
                        if (!valueWasRetrieved)
                        {
                            value             = INTERNAL_PropertyStore.GetEffectiveValue(storage);
                            valueWasRetrieved = true;
                        }

                        // Call the "Method to update DOM"
                        propertyMetadata.MethodToUpdateDom(storage.Owner, value);
                    }

                    //--------------------------------------------------
                    // Call PropertyChanged
                    //--------------------------------------------------

                    if (propertyMetadata.PropertyChangedCallback != null &&
                        propertyMetadata.CallPropertyChangedWhenLoadedIntoVisualTree != WhenToCallPropertyChangedEnum.Never)
                    {
                        if (!valueWasRetrieved)
                        {
                            value             = INTERNAL_PropertyStore.GetEffectiveValue(storage);
                            valueWasRetrieved = true;
                        }

                        // Raise the "PropertyChanged" event
                        propertyMetadata.PropertyChangedCallback(storage.Owner, new DependencyPropertyChangedEventArgs(value, value, property));
                    }
                }


#if PERFSTAT
                Performance.Counter("VisualTreeManager: RaisePropertyChanged for property '" + property.Name + "'", t1);
#endif
            }
        }
コード例 #2
0
        static void RenderElementsAndRaiseChangedEventOnAllDependencyProperties(DependencyObject dependencyObject)
        {
            //#if CSHTML5BLAZOR && DEBUG
            //            string prettyPrintDependencyObject = dependencyObject + (dependencyObject != null ? "(" + dependencyObject.GetHashCode().ToString() +")" : "");
            //            Console.WriteLine("OPENSILVER DEBUG: VisualTreeManager: RenderElementsAndRaiseChangedEventOnAllDependencyProperties: dependencyObject:" + prettyPrintDependencyObject);
            //#endif

            // To prevent raising the property multiple times, we keep track of the properties for which we already raised the "PropertyChanged" event:
            //Dictionary<DependencyProperty, DependencyProperty> propertiesForWhichTheEventHasAlreadyBeenRaised = new Dictionary<DependencyProperty, DependencyProperty>(); //todo: replace with HashSet<DependencyProperty> when available.

            //------------------------------------------------------------------------------------------------------------------
            // RAISE "PROPERTYCHANGED" FOR ALL THE PROPERTIES THAT HAVE A VALUE THAT HAS BEEN SET, INCLUDING ATTACHED PROPERTIES, AND CALL THE "METHOD TO UPDATE DOM":
            //------------------------------------------------------------------------------------------------------------------

            // This is used to force a redraw of all the properties that are set on the object (including Attached Properties!). For example, if a Border has a colored background, this is the moment when that color will be applied. Properties that have no value set by the user are not concerned (their default state is rendered elsewhere).
            if (dependencyObject.INTERNAL_PropertyStorageDictionary != null)
            {
#if PERFSTAT
                var t0 = Performance.now();
#endif
                var list = dependencyObject.INTERNAL_PropertyStorageDictionary.ToList <KeyValuePair <DependencyProperty, INTERNAL_PropertyStorage> >(); //we copy the Dictionary so that the foreach doesn't break when we modify a DependencyProperty inside the Changed of another one (which causes it to be added to the Dictionary).
#if PERFSTAT
                Performance.Counter("VisualTreeManager: Copy list of properties", t0);
#endif
                foreach (KeyValuePair <DependencyProperty, INTERNAL_PropertyStorage> propertiesAndTheirStorage in list)
                {
                    // Read the value:
                    DependencyProperty property = propertiesAndTheirStorage.Key;

#if PERFSTAT
                    var t1 = Performance.now();
#endif

                    PropertyMetadata propertyMetadata = property.GetTypeMetaData(dependencyObject.GetType());
                    //#if CSHTML5BLAZOR && DEBUG
                    //                    string prettyPrintProperty = property.Name + (property != null ? "(" + property.GetHashCode().ToString() + ")" : "");
                    //                    Console.WriteLine("OPENSILVER DEBUG: VisualTreeManager: RenderElementsAndRaiseChangedEventOnAllDependencyProperties:"
                    //                        + " dependencyObject:" + prettyPrintDependencyObject
                    //                        + " property:" + prettyPrintProperty
                    //                        + " MSG: " + (propertyMetadata != null ? "has" : "has not") + " a propertyMetadata");
                    //#endif
                    if (propertyMetadata != null)
                    {
                        INTERNAL_PropertyStorage storage = propertiesAndTheirStorage.Value;
                        object value             = null;
                        bool   valueWasRetrieved = false;

                        //--------------------
                        // Call "Apply CSS", which uses "GetCSSEquivalent/s":
                        //--------------------
                        if (propertyMetadata.GetCSSEquivalent != null || propertyMetadata.GetCSSEquivalents != null)
                        {
                            if (!valueWasRetrieved)
                            {
                                value             = INTERNAL_PropertyStore.GetValue(storage, propertyMetadata);
                                valueWasRetrieved = true;
                            }

                            INTERNAL_PropertyStore.ApplyCssChanges(value, value, propertyMetadata, storage.Owner);
                        }

                        //--------------------
                        // Call "MethodToUpdateDom":
                        //--------------------
                        if (propertyMetadata.MethodToUpdateDom != null)
                        {
                            if (!valueWasRetrieved)
                            {
                                value             = INTERNAL_PropertyStore.GetValue(storage, propertyMetadata);
                                valueWasRetrieved = true;
                            }

                            // Call the "Method to update DOM":
                            propertyMetadata.MethodToUpdateDom(storage.Owner, value);
                        }

                        //--------------------
                        // Call PropertyChanged:
                        //--------------------
                        //#if CSHTML5BLAZOR && DEBUG
                        //                        string prettyPrintPropertyMetadata = propertyMetadata + (propertyMetadata != null ? propertyMetadata.GetHashCode().ToString() : "");
                        //                        Console.WriteLine("OPENSILVER DEBUG: VisualTreeManager: RenderElementsAndRaiseChangedEventOnAllDependencyProperties:"
                        //                            + " dependencyObject:" + prettyPrintDependencyObject
                        //                            + " property:" + prettyPrintProperty
                        //                            + " propertyMetadata:" + propertyMetadata
                        //                            + " MSG: " + (propertyMetadata.PropertyChangedCallback != null ? "has" : "has not") + " a PropertyChangedCallback" );
                        //#endif
                        if (propertyMetadata.PropertyChangedCallback != null &&
                            propertyMetadata.CallPropertyChangedWhenLoadedIntoVisualTree != WhenToCallPropertyChangedEnum.Never)
                        {
                            if (!valueWasRetrieved)
                            {
                                value             = INTERNAL_PropertyStore.GetValue(storage, propertyMetadata);
                                valueWasRetrieved = true;
                            }

                            //#if CSHTML5BLAZOR && DEBUG
                            //                            Console.WriteLine("OPENSILVER DEBUG: VisualTreeManager: RenderElementsAndRaiseChangedEventOnAllDependencyProperties:"
                            //                                + " dependencyObject:" + prettyPrintDependencyObject
                            //                                + " property:" + prettyPrintProperty
                            //                                + " propertyMetadata:" + propertyMetadata
                            //                                + " MSG: is raising PropertyChangedCallback)");
                            //#endif
                            // Raise the "PropertyChanged" event:
                            propertyMetadata.PropertyChangedCallback(storage.Owner, new DependencyPropertyChangedEventArgs(value, value, property));

                            // Remember that we raised the event, to avoid raising it again in the code below:
                            //propertiesForWhichTheEventHasAlreadyBeenRaised.Add(property, property); //commented since the "code below" is commented
                        }
                    }


#if PERFSTAT
                    Performance.Counter("VisualTreeManager: RaisePropertyChanged for property '" + property.Name + "'", t1);
#endif
                }
            }

            /*
             * //------------------------------------------------------------------------------------
             * // RAISE "PROPERTYCHANGED" FOR ALL THE OTHER PROPERTIES THAT REQUIRE IT
             * //------------------------------------------------------------------------------------
             *
             * // When a dependency property is not set, we usually do not raise the "PropertyChanged" event, unless the property has its "CallPropertyChangedWhenLoadedIntoVisualTree" property set to "Always" in its TypeMetadata:
             * var type = dependencyObject.GetType();
             * // Iterate through all the inheritance parents of the type (we use a Stack to revert the order):
             * Stack<Type> typeAndItsInheritanceParents = new Stack<Type>();
             * while (type != null)
             * {
             *  typeAndItsInheritanceParents.Push(type);
             *  type = type.BaseType;
             * }
             * while (typeAndItsInheritanceParents.Count > 0)
             * {
             *  type = typeAndItsInheritanceParents.Pop();
             *  if (INTERNAL_TypeToDependencyPropertiesThatRequirePropertyChanged.TypeToDependencyPropertiesThatRequirePropertyChanged.ContainsKey(type))
             *  {
             *      // Raise the "PropertyChanged" for all the DependencyProperties of the object that require it:
             *      foreach (DependencyProperty dependencyProperty in INTERNAL_TypeToDependencyPropertiesThatRequirePropertyChanged.TypeToDependencyPropertiesThatRequirePropertyChanged[type])
             *      {
             *          if (!propertiesForWhichTheEventHasAlreadyBeenRaised.ContainsKey(dependencyProperty)
             *              && dependencyProperty.TypeMetadata.PropertyChangedCallback != null)
             *          {
             *              // Get the value:
             *              object value;
             *              if (dependencyObject.INTERNAL_PropertyStorageDictionary.ContainsKey(dependencyProperty))
             *                  value = dependencyObject.GetValue(dependencyProperty);
             *              else if (dependencyProperty.TypeMetadata != null)
             *                  value = dependencyProperty.TypeMetadata.DefaultValue;
             *              else
             *                  value = null;
             *
             *              // Raise the "PropertyChanged":
             *              dependencyProperty.TypeMetadata.PropertyChangedCallback(dependencyObject, new DependencyPropertyChangedEventArgs(value, value, dependencyProperty));
             *          }
             *      }
             *  }
             * }
             */
        }