예제 #1
0
        /// <summary>
        /// An Animatable will return false from this method if there are any Clocks
        /// animating any of its properties. If the Animatable has persistent animations
        /// specified, but all of the Clocks have been removed, it may still return
        /// true from this method if the Timelines themselves can be frozen.
        /// </summary>
        /// <param name="isChecking">
        /// True if the Freezable should actually Freeze itself; false if
        /// the Freezable should simply return whether it can be frozen.</param>
        /// <returns>True if this object can be frozen; otherwise false.</returns>
        protected override bool FreezeCore(bool isChecking)
        {
            if (IAnimatable_HasAnimatedProperties)
            {
                if (TraceFreezable.IsEnabled)
                {
                    TraceFreezable.Trace(
                        TraceEventType.Warning,
                        TraceFreezable.UnableToFreezeAnimatedProperties,
                        this);
                }

                return(false);
            }

            return(base.FreezeCore(isChecking));
        }
        private static bool DefaultFreezeValueCallback(
            DependencyObject d,
            DependencyProperty dp,
            EntryIndex entryIndex,
            PropertyMetadata metadata,
            bool isChecking)
        {
            // The expression check only needs to be done when isChecking is true
            // because if we return false here the Freeze() call will fail.
            if (isChecking)
            {
                if (d.HasExpression(entryIndex, dp))
                {
                    if (TraceFreezable.IsEnabled)
                    {
                        TraceFreezable.Trace(
                            TraceEventType.Warning,
                            TraceFreezable.UnableToFreezeExpression,
                            d,
                            dp,
                            dp.OwnerType);
                    }

                    return(false);
                }
            }

            if (!dp.IsValueType)
            {
                object value =
                    d.GetValueEntry(
                        entryIndex,
                        dp,
                        metadata,
                        RequestFlags.FullyResolved).Value;

                if (value != null)
                {
                    Freezable valueAsFreezable = value as Freezable;

                    if (valueAsFreezable != null)
                    {
                        if (!valueAsFreezable.Freeze(isChecking))
                        {
                            if (TraceFreezable.IsEnabled)
                            {
                                TraceFreezable.Trace(
                                    TraceEventType.Warning,
                                    TraceFreezable.UnableToFreezeFreezableSubProperty,
                                    d,
                                    dp,
                                    dp.OwnerType);
                            }

                            return(false);
                        }
                    }
                    else  // not a Freezable
                    {
                        DispatcherObject valueAsDispatcherObject = value as DispatcherObject;

                        if (valueAsDispatcherObject != null)
                        {
                            if (valueAsDispatcherObject.Dispatcher == null)
                            {
                                // The property is a free-threaded DispatcherObject; since it's
                                // already free-threaded it doesn't prevent this Freezable from
                                // becoming free-threaded too.
                                // It is up to the creator of this type to ensure that the
                                // DispatcherObject is actually immutable
                            }
                            else
                            {
                                // The value of this property derives from DispatcherObject and
                                // has thread affinity; return false.

                                if (TraceFreezable.IsEnabled)
                                {
                                    TraceFreezable.Trace(
                                        TraceEventType.Warning,
                                        TraceFreezable.UnableToFreezeDispatcherObjectWithThreadAffinity,
                                        d,
                                        dp,
                                        dp.OwnerType,
                                        valueAsDispatcherObject);
                                }

                                return(false);
                            }
                        }

                        // The property isn't a DispatcherObject.  It may be immutable (such as a string)
                        // or the user may have made it thread-safe.  It's up to the creator of the type to
                        // do the right thing; we return true as an extensibility point.
                    }
                }
            }

            return(true);
        }