Style.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Style.cs / 1 / Style.cs

                            /****************************************************************************\ 
*
* File: Style.cs
*
*  Style and templating. 
*
* Copyright (C) 2003 by Microsoft Corporation.  All rights reserved. 
* 
\***************************************************************************/
 
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.ComponentModel; 
using System.Diagnostics;  // For Debug.Assert
using System.Windows.Threading; 
using System.Threading; 
using System.Windows.Controls;
using System.Windows.Data; 
using System.Windows.Media;
using System.Windows.Media.Animation; // For Storyboard support
using System.Windows.Markup;
using System.Security.Permissions; 
using System.IO;
using MS.Utility; 
using MS.Internal; 
using System;
 
#pragma warning disable 1634, 1691  // suppressing PreSharp warnings

namespace System.Windows
{ 
    /// 
    ///     Styling and Templating 
    ///  
    [Localizability(LocalizationCategory.Ignore)]
    [ContentProperty("Setters")] 
    public class Style : DispatcherObject, INameScope, IAddChild, ISealable, IHaveResources
    {
        static Style()
        { 
            // Register for the "alternative Expression storage" feature, since
            // we store Expressions in per-instance StyleData. 
            StyleHelper.RegisterAlternateExpressionStorage(); 
        }
 
        /// 
        ///     Style construction
        /// 
        public Style() 
        {
            GetUniqueGlobalIndex(); 
        } 

        ///  
        ///     Style construction
        /// 
        /// Type in which Style will be applied
        public Style(Type targetType) 
        {
            TargetType = targetType; 
 
            GetUniqueGlobalIndex();
        } 

        /// 
        ///     Style construction
        ///  
        /// Type in which Style will be applied
        /// Style to base this Style on 
        public Style(Type targetType, Style basedOn) 
        {
            TargetType = targetType; 
            BasedOn = basedOn;

            GetUniqueGlobalIndex();
        } 

        #region INameScope 
        ///  
        /// Registers the name - Context combination
        ///  
        /// Name to register
        /// Element where name is defined
        public void RegisterName(string name, object scopedElement)
        { 
            // Verify Context Access
            VerifyAccess(); 
 
            _nameScope.RegisterName(name, scopedElement);
        } 

        /// 
        /// Unregisters the name - element combination
        ///  
        /// Name of the element
        public void UnregisterName(string name) 
        { 
            // Verify Context Access
            VerifyAccess(); 

            _nameScope.UnregisterName(name);
        }
 
        /// 
        /// Find the element given name 
        ///  
        /// Name of the element
        object INameScope.FindName(string name) 
        {
            // Verify Context Access
            VerifyAccess();
 
            return _nameScope.FindName(name);
        } 
 
        private NameScope _nameScope = new NameScope();
        #endregion IIdScope 

        /// 
        /// Each Style gets its own unique index used for Style.GetHashCode
        ///  
        private void GetUniqueGlobalIndex()
        { 
            lock (Synchronized) 
            {
                // Setup unqiue global index 
                StyleInstanceCount++;
                GlobalIndex = StyleInstanceCount;
            }
        } 

        ///  
        ///     Style mutability state 
        /// 
        ///  
        ///     A style is sealed when another style is basing on it, or,
        ///     when it's applied
        /// 
        public bool IsSealed 
        {
            get 
            { 
                // Verify Context Access
                VerifyAccess(); 

                return _sealed;
            }
        } 

 
        ///  
        ///     Type that this style is intended
        ///  
        /// 
        ///     By default, the target type is FrameworkElement
        /// 
        [Localizability(LocalizationCategory.NeverLocalize)] 
        public Type TargetType
        { 
            get 
            {
                // Verify Context Access 
                VerifyAccess();

                return _targetType;
            } 

            set 
            { 
                // Verify Context Access
                VerifyAccess(); 

                if (_sealed)
                {
                    throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Style")); 
                }
 
                if( value == null ) 
                {
                    throw new ArgumentNullException("value"); 
                }

                if (!typeof(FrameworkElement).IsAssignableFrom(value) &&
                    !typeof(FrameworkContentElement).IsAssignableFrom(value) && 
                    !(DefaultTargetType == value))
                { 
                    #pragma warning suppress 6506 // value is obviously not null 
                    throw new ArgumentException(SR.Get(SRID.MustBeFrameworkDerived, value.Name));
                } 

                _targetType = value;

                SetModified(TargetTypeID); 
            }
        } 
 
        /// 
        ///     Style to base on 
        /// 
        [DefaultValue(null)]
        public Style BasedOn
        { 
            get
            { 
                // Verify Context Access 
                VerifyAccess();
 
                return _basedOn;
            }
            set
            { 
                // Verify Context Access
                VerifyAccess(); 
 
                if (_sealed)
                { 
                    throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Style"));
                }

                if( value == this ) 
                {
                    // Basing on self is not allowed.  This is a degenerate case 
                    //  of circular reference chain, the full check for circular 
                    //  reference is done in Seal().
                    throw new ArgumentException(SR.Get(SRID.StyleCannotBeBasedOnSelf)); 
                }

                _basedOn = value;
 
                SetModified(BasedOnID);
            } 
        } 

 
        /// 
        ///     Visual triggers
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
        public TriggerCollection Triggers
        { 
            get 
            {
                // Verify Context Access 
                VerifyAccess();

                if (_visualTriggers == null)
                { 
                    _visualTriggers = new TriggerCollection();
 
                    // If the style has been sealed prior to this the newly 
                    // created TriggerCollection also needs to be sealed
                    if (_sealed) 
                    {
                        _visualTriggers.Seal();
                    }
                } 
                return _visualTriggers;
            } 
        } 

        ///  
        ///     The collection of property setters for the target type
        /// 

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
        public SetterBaseCollection Setters
        { 
            get 
            {
                // Verify Context Access 
                VerifyAccess();

                if( _setters == null )
                { 
                    _setters = new SetterBaseCollection();
 
                    // If the style has been sealed prior to this the newly 
                    // created SetterBaseCollection also needs to be sealed
                    if (_sealed) 
                    {
                        _setters.Seal();
                    }
                } 
                return _setters;
            } 
        } 

        ///  
        ///     The collection of resources that can be
        ///     consumed by the container and its sub-tree.
        /// 
        public ResourceDictionary Resources 
        {
            get 
            { 
                // Verify Context Access
                VerifyAccess(); 

                if( _resources == null )
                {
                    _resources = new ResourceDictionary(); 

                    // A Style ResourceDictionary can be accessed across threads 
                    _resources.CanBeAccessedAcrossThreads = true; 

                    // If the style has been sealed prior to this the newly 
                    // created ResourceDictionary also needs to be sealed
                    if (_sealed)
                    {
                        _resources.IsReadOnly = true; 
                    }
                } 
                return _resources; 
            }
            set 
            {
                // Verify Context Access
                VerifyAccess();
 
                if( _sealed )
                { 
                    throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Style")); 
                }
 
                _resources = value;

                if (_resources != null)
                { 
                    // A Style ResourceDictionary can be accessed across threads
                    _resources.CanBeAccessedAcrossThreads = true; 
                } 
            }
        } 

        ResourceDictionary IHaveResources.Resources
        {
            get { return Resources; } 
            set { Resources = value; }
        } 
 
        /// 
        ///     Tries to find a Reosurce for the given resourceKey in the current 
        ///     style's ResourceDictionary or the basedOn style's ResourceDictionary
        ///     in that order.
        /// 
        internal object FindResource(object resourceKey, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference) 
        {
            if ((_resources != null) && _resources.Contains(resourceKey)) 
            { 
                bool canCache;
                return _resources.FetchResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); 
            }
            if (_basedOn != null)
            {
                return _basedOn.FindResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference); 
            }
            return DependencyProperty.UnsetValue; 
        } 

        /// 
        /// This method is called to Add a Setter object as a child of the Style.
        /// This method is used primarily by the parser to set style properties and events.
        ///
        /// 
        /// The object to add as a child; it must be a SetterBase subclass.
        /// 
        void IAddChild.AddChild (Object value) 
        {
            // Verify Context Access 
            VerifyAccess();

            if (value == null)
            { 
                throw new ArgumentNullException("value");
            } 
 
            SetterBase sb = value as SetterBase;
 
            if (sb == null)
            {
                throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(SetterBase)), "value");
            } 

            Setters.Add(sb); 
        } 

        /// 
        /// This method is called by the parser when text appears under the tag in markup.
        /// As default Styles do not support text, calling this method has no effect.
        ///
        /// 
        /// Text to add as a child.
        /// 
        void IAddChild.AddText (string text) 
        {
            // Verify Context Access 
            VerifyAccess();

            XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
        } 

        ///  
        ///     Given a set of values for the PropertyValue struct, put that in 
        /// to the PropertyValueList, overwriting any existing entry.
        ///  
        private void UpdatePropertyValueList(
            DependencyProperty dp,
            PropertyValueType valueType,
            object value) 
        {
            // Check for existing value on dp 
            int existingIndex = -1; 
            for( int i = 0; i < PropertyValues.Count; i++ )
            { 
                if( PropertyValues[i].Property == dp )
                {
                    existingIndex = i;
                    break; 
                }
            } 
 
            if( existingIndex >= 0 )
            { 
                // Overwrite existing value for dp
                PropertyValue propertyValue = PropertyValues[existingIndex];
                propertyValue.ValueType = valueType;
                propertyValue.ValueInternal = value; 
                // Put back modified struct
                PropertyValues[existingIndex] = propertyValue; 
            } 
            else
            { 
                // Store original data
                PropertyValue propertyValue = new PropertyValue();
                propertyValue.ValueType = valueType;
                propertyValue.ChildName = StyleHelper.SelfName; 
                propertyValue.Property = dp;
                propertyValue.ValueInternal = value; 
 
                PropertyValues.Add(propertyValue);
            } 
        }

        internal void CheckTargetType(object element)
        { 
            // In the most common case TargetType is Default
            // and we can avoid a call to IsAssignableFrom() who's performance is unknown. 
            if(DefaultTargetType == TargetType) 
                return;
 
            Type elementType = element.GetType();
            if(!TargetType.IsAssignableFrom(elementType))
            {
                throw new InvalidOperationException(SR.Get(SRID.StyleTargetTypeMismatchWithElement, 
                                                    this.TargetType.Name,
                                                    elementType.Name)); 
            } 
        }
 
        /// 
        /// This Style and all factories/triggers are now immutable
        /// 
        public void Seal() 
        {
            // Verify Context Access 
            VerifyAccess(); 

            // 99% case - Style is already sealed. 
            if (_sealed)
            {
                return;
            } 

            // Most parameter checking is done as "upstream" as possible, but some 
            //  can't be checked until Style is sealed. 
            if (_targetType == null)
            { 
                throw new InvalidOperationException(SR.Get(SRID.NullPropertyIllegal, "TargetType"));
            }

            if (_basedOn != null) 
            {
                if(DefaultTargetType != _basedOn.TargetType && 
                    !_basedOn.TargetType.IsAssignableFrom(_targetType)) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.MustBaseOnStyleOfABaseType, _targetType.Name)); 
                }
            }

            // Seal setters 
            if (_setters != null)
            { 
                _setters.Seal(); 
            }
 
            // Seal triggers
            if (_visualTriggers != null)
            {
                _visualTriggers.Seal(); 
            }
 
            // Will throw InvalidOperationException if we find a loop of 
            //  BasedOn references.  (A.BasedOn = B, B.BasedOn = C, C.BasedOn = A)
            CheckForCircularBasedOnReferences(); 

            // Seal BasedOn Style chain
            if (_basedOn != null)
            { 
                _basedOn.Seal();
            } 
 
            // Seal the ResourceDictionary
            if (_resources != null) 
            {
                _resources.IsReadOnly = true;
            }
 
            //
            // Build shared tables 
            // 

            // Process all Setters set on the selfStyle. This stores all the property 
            // setters on the current styles into PropertyValues list, so it can be used
            // by ProcessSelfStyle in the next step. The EventSetters for the current
            // and all the basedOn styles are merged into the EventHandlersStore on the
            // current style. 
            ProcessSetters(this);
 
            // Add an entry in the EventDependents list for 
            // the TargetType's EventHandlersStore. Notice
            // that the childIndex is 0. 
            StyleHelper.AddEventDependent(0, this.EventHandlersStore, ref EventDependents);

            // Process all PropertyValues (all are "Self") in the Style
            // chain (base added first) 
            ProcessSelfStyles(this);
 
            // Process all TriggerBase PropertyValues ("Self" triggers 
            // and child triggers) in the Style chain last (highest priority)
            ProcessVisualTriggers(this); 

            // Sort the ResourceDependents, to help avoid duplicate invalidations
            StyleHelper.SortResourceDependents(ref ResourceDependents);
 
            // All done, seal self and call it a day.
            _sealed = true; 
 
            // Remove thread affinity so it can be accessed across threads
            DetachFromDispatcher(); 
        }

        /// 
        ///     This method checks to see if the BasedOn hierarchy contains 
        /// a loop in the chain of references.
        ///  
        ///  
        /// Classic "when did we enter the cycle" problem where we don't know
        ///  what to start remembering and what to check against.  Brute- 
        ///  force approach here is to remember everything with a stack
        ///  and do a linear comparison through everything.  Since the Style
        ///  BasedOn hierarchy is not expected to be large, this should be OK.
        ///  
        private void CheckForCircularBasedOnReferences()
        { 
            Stack basedOnHierarchy = new Stack(10);  // 10 because that's the default value (see MSDN) and the perf team wants us to specify something. 
            Style latestBasedOn = this;
 
            while( latestBasedOn != null )
            {
                if( basedOnHierarchy.Contains( latestBasedOn ) )
                { 
                    // Uh-oh.  We've seen this Style before.  This means
                    //  the BasedOn hierarchy contains a loop. 
                    throw new InvalidOperationException(SR.Get( 
                        SRID.StyleBasedOnHasLoop));
 
                    // Debugging note: If we stop here, the basedOnHierarchy
                    //  object is still alive and we can browse through it to
                    //  see what we've explored.  (This does not apply if
                    //  somebody catches this exception and re-throws.) 
                }
 
                // Haven't seen it, push on stack and go to next level. 
                basedOnHierarchy.Push( latestBasedOn );
                latestBasedOn = latestBasedOn.BasedOn; 
            }

            return;
        } 

        // Iterates through the setters collection and adds the EventSetter information into 
        // an EventHandlersStore for easy and fast retrieval during event routing. Also adds 
        // an entry in the EventDependents list for EventhandlersStore holding the TargetType's
        // events. 
        private void ProcessSetters(Style style)
        {
            // Walk down to bottom of based-on chain
            if (style == null) 
            {
                return; 
            } 

            style.Setters.Seal(); // Does not mark individual setters as sealed, that's up to the loop below. 


            // On-demand create the PropertyValues list, so that we can specify the right size.
 
            if(PropertyValues.Count == 0)
            { 
                PropertyValues = new FrugalStructList(style.Setters.Count); 
            }
 
            // Add EventSetters to local EventHandlersStore
            for (int i = 0; i < style.Setters.Count; i++)
            {
                SetterBase setterBase = style.Setters[i]; 
                Debug.Assert(setterBase != null, "Setter collection must contain non-null instances of SetterBase");
 
                // Setters are folded into the PropertyValues table only for the current style. The 
                // processing of BasedOn Style properties will occur in subsequent call to ProcessSelfStyle
                Setter setter = setterBase as Setter; 
                if (setter != null)
                {
                    // Style Setters are not allowed to have a child target name - since there are no child nodes in a Style.
                    if( setter.TargetName != null ) 
                    {
                        throw new InvalidOperationException(SR.Get(SRID.SetterOnStyleNotAllowedToHaveTarget, setter.TargetName)); 
                    } 

                    if (style == this) 
                    {
                        DynamicResourceExtension dynamicResource = setter.ValueInternal as DynamicResourceExtension;
                        if (dynamicResource == null)
                        { 
                            UpdatePropertyValueList( setter.Property, PropertyValueType.Set, setter.ValueInternal );
                        } 
                        else 
                        {
                            UpdatePropertyValueList( setter.Property, PropertyValueType.Resource, dynamicResource.ResourceKey ); 
                        }
                    }
                }
                else 
                {
 
                    Debug.Assert(setterBase is EventSetter, 
                                 "Unsupported SetterBase subclass in style triggers ({0})", setterBase.GetType().ToString());
 
                    // Add this to the _eventHandlersStore

                    EventSetter eventSetter = (EventSetter)setterBase;
                    if (_eventHandlersStore == null) 
                    {
                        _eventHandlersStore = new EventHandlersStore(); 
                    } 
                    _eventHandlersStore.AddRoutedEventHandler(eventSetter.Event, eventSetter.Handler, eventSetter.HandledEventsToo);
 
                    SetModified(HasEventSetter);

                    // If this event setter watches the loaded/unloaded events, set the optimization
                    // flag. 

                    if (eventSetter.Event == FrameworkElement.LoadedEvent || eventSetter.Event == FrameworkElement.UnloadedEvent) 
                    { 
                        _hasLoadedChangeHandler = true;
                    } 


                }
            } 

            // Process EventSetters on based on style so they get merged 
            // into the EventHandlersStore for the current style. 
            ProcessSetters(style._basedOn);
        } 

        private void ProcessSelfStyles(Style style)
        {
            // Walk down to bottom of based-on chain 
            if (style == null)
            { 
                return; 
            }
 
            ProcessSelfStyles(style._basedOn);

            // Merge in "self" PropertyValues while walking back up the tree
            // "Based-on" style "self" rules are always added first (lower priority) 
            for (int i = 0; i < style.PropertyValues.Count; i++)
            { 
                PropertyValue propertyValue = style.PropertyValues[i]; 

                StyleHelper.UpdateTables(ref propertyValue, ref ChildRecordFromChildIndex, 
                    ref TriggerSourceRecordFromChildIndex, ref ResourceDependents, ref _dataTriggerRecordFromBinding,
                    null /*_childIndexFromChildID*/, ref _hasInstanceValues);

                // Track properties on the container that are being driven by 
                // the Style so that they can be invalidated during style changes
                StyleHelper.AddContainerDependent(propertyValue.Property, false /*fromVisualTrigger*/, ref ContainerDependents); 
            } 
        }
 
        private void ProcessVisualTriggers(Style style)
        {
            // Walk down to bottom of based-on chain
            if (style == null) 
            {
                return; 
            } 

            ProcessVisualTriggers(style._basedOn); 

            if (style._visualTriggers != null)
            {
                // Merge in "self" and child TriggerBase PropertyValues while walking 
                // back up the tree. "Based-on" style rules are always added first
                // (lower priority) 
                int triggerCount = style._visualTriggers.Count; 
                for (int i = 0; i < triggerCount; i++)
                { 
                    TriggerBase trigger = style._visualTriggers[i];

                    // Set things up to handle Setter values
                    for (int j = 0; j < trigger.PropertyValues.Count; j++) 
                    {
                        PropertyValue propertyValue = trigger.PropertyValues[j]; 
 
                        // Check for trigger rules that act on container
                        if (propertyValue.ChildName != StyleHelper.SelfName) 
                        {
                            throw new InvalidOperationException(SR.Get(SRID.StyleTriggersCannotTargetTheTemplate));
                        }
 
                        TriggerCondition[] conditions = propertyValue.Conditions;
                        for (int k=0; k 0 )
                        {
                            throw new InvalidOperationException(SR.Get(SRID.EventTriggerOnStyleNotAllowedToHaveTarget, eventTrigger.SourceName));
                        } 

                        StyleHelper.ProcessEventTrigger(eventTrigger, 
                                                        null /*_childIndexFromChildID*/, 
                                                        ref _triggerActions,
                                                        ref EventDependents, 
                                                        null /*_templateFactoryRoot*/,
                                                        null,
                                                        ref _eventHandlersStore,
                                                        ref _hasLoadedChangeHandler); 
                    }
                } 
            } 
        }
 
        /// 
        ///     Serves as a hash function for a particular type, suitable for use in
        ///     hashing algorithms and data structures like a hash table
        ///  
        /// The Style's GlobalIndex
        public override int GetHashCode() 
        { 
            // Verify Context Access
            VerifyAccess(); 

            return GlobalIndex;
        }
 
        #region ISealable
 
        ///  
        /// Can this style be sealed
        ///  
        bool ISealable.CanSeal
        {
            get { return true; }
        } 

        ///  
        /// Is this style sealed 
        /// 
        bool ISealable.IsSealed 
        {
            get { return IsSealed; }
        }
 
        /// 
        /// Seal this style 
        ///  
        void ISealable.Seal()
        { 
            Seal();
        }

        #endregion ISealable 

        internal bool HasResourceReferences 
        { 
            get
            { 
                return ResourceDependents.Count > 0;
            }
        }
 
        /// 
        ///     Store all the event handlers for this Style TargetType 
        ///  
        internal EventHandlersStore EventHandlersStore
        { 
            get { return _eventHandlersStore; }
        }

        ///  
        ///     Does the current style or any of its template children
        ///     have any event setters OR event triggers 
        ///  
        internal bool HasEventDependents
        { 
            get
            {
                return (EventDependents.Count > 0);
            } 
        }
 
        ///  
        ///     Does the current style or any of its template children
        ///     have event setters, ignoring event triggers. 
        /// 
        internal bool HasEventSetters
        {
            get 
            {
                return IsModified(HasEventSetter); 
            } 
        }
 
        //
        //  Says if this style contains any per-instance values
        //
        internal bool HasInstanceValues 
        {
            get { return _hasInstanceValues; } 
        } 

        // 
        // Says if we have anything listening for the Loaded or Unloaded
        // event (used for an optimization in FrameworkElement).
        //
 
        internal bool HasLoadedChangeHandler
        { 
            get { return _hasLoadedChangeHandler; } 
            set { _hasLoadedChangeHandler = value; }
        } 

        // Special equality check that takes into account 'null'
        private static bool IsEqual(object a, object b)
        { 
            return (a != null) ? a.Equals(b) : (b == null);
        } 
 
        internal bool IsBasedOnModified { get { return IsModified(BasedOnID); } }
 
        private EventHandlersStore _eventHandlersStore = null;

        private bool _sealed;
        private bool _hasInstanceValues; 

        internal static readonly Type DefaultTargetType = typeof(IFrameworkInputElement); 
 
        private bool _hasLoadedChangeHandler;
 
        private Type _targetType = DefaultTargetType;
        private Style _basedOn;

        private TriggerCollection _visualTriggers = null; 

        private SetterBaseCollection _setters = null; 
 
        // Holds resources that are applicable to the container
        // of this style and its sub-tree. 
        internal ResourceDictionary _resources = null;

        /* property */ internal int GlobalIndex;
 
        // Style tables
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock 
        /* property */ internal FrugalStructList ChildRecordFromChildIndex = new FrugalStructList(); // Indexed by Child.ChildIndex 
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock
 
        //
        // Shared tables used during OnTriggerSourcePropertyInvalidated
        //
        internal FrugalStructList> TriggerSourceRecordFromChildIndex = new FrugalStructList>(); 
        // Dictionary of property triggers that have TriggerActions, keyed via DP.GlobalIndex affecting those triggers.
        //  Each trigger can be listed multiple times, if they are dependent on multiple properties. 
        internal FrugalMap PropertyTriggersWithActions; 

        // Original Style data (not including based-on data) 
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock
        /* property */ internal FrugalStructList PropertyValues = new FrugalStructList();

        // Properties driven on the container (by the Style) that should be 
        // invalidated when the style gets applied/unapplied. These properties
        // could have been set via Style.SetValue or TriggerBase.SetValue 
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock 
        /* property */ internal FrugalStructList ContainerDependents = new FrugalStructList();
 
        // Properties driven by a resource that should be invalidated
        // when a resource dictionary changes
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock
        /* property */ internal FrugalStructList ResourceDependents = new FrugalStructList(); 

        // Events driven by a this style. An entry for every childIndex that has associated events. 
        // childIndex '0' is used to represent events set on the style's TargetType. This data-structure 
        // will be frequently looked up during event routing.
        // Synchronized (write locks, lock-free reads): Covered by Style instance lock 
        /* property */ internal ItemStructList EventDependents = new ItemStructList(1);

        // Used by EventTrigger: Maps a RoutedEventID to a set of TriggerAction objects
        //  to be performed. 
        internal HybridDictionary _triggerActions = null;
 
        // Data trigger information.  An entry for each Binding that appears in a 
        // condition of a data trigger.
        // Synchronized: Covered by Style instance 
        internal HybridDictionary _dataTriggerRecordFromBinding;

        // An entry for each Binding that appears in a DataTrigger with EnterAction or ExitAction
        //  This overlaps but should not be the same as _dataTriggerRecordFromBinding above: 
        //   A DataTrigger can have Setters but no EnterAction/ExitAction.  (The reverse can also be true.)
        internal HybridDictionary DataTriggersWithActions = null; 
 
        // Unique index for every instance of Style
        // Synchronized: Covered by Style.Synchronized 
        private static int StyleInstanceCount = 0;

        // Global, cross-object synchronization
        internal static object Synchronized = new object(); 

        private const int TargetTypeID = 0x01; 
        internal const int BasedOnID    = 0x02; 

        // Using the modified flags to note whether we have an EventSetter. 
        private const int HasEventSetter = 0x10;

        private int _modified = 0;
 
        private void SetModified(int id) { _modified |= id; }
        internal bool IsModified(int id) { return (id & _modified) != 0; } 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK