コード例 #1
0
ファイル: Maps.cs プロジェクト: JianwenSun/cc
 public DTypeMap(int entryCount)
 {
     // Constant Time Lookup entries (array size)
     _entryCount = entryCount;
     _entries = new object[_entryCount];
     _activeDTypes = new ItemStructList<DependencyObjectType>(128);
 }
コード例 #2
0
        // Returns a copy of the list of registered RoutedEvents
        // Returns a copy of the list so the original cannot be modified
        internal static RoutedEvent[] GetRoutedEvents()
        {
            RoutedEvent[] routedEvents;

            lock (Synchronized)
            {
                // Requires GlobalLock to access _countRoutedEvents
                routedEvents = new RoutedEvent[_countRoutedEvents];

                // Enumerate through all of the RoutedEvents in the DTypeMap
                // Requires GlobalLock to access _dTypedRoutedEventList
                ItemStructList <DependencyObjectType> keys = _dTypedRoutedEventList.ActiveDTypes;

                int destIndex = 0;
                for (int i = 0; i < keys.Count; i++)
                {
                    FrugalObjectList <RoutedEvent> dTypedRoutedEventList = (FrugalObjectList <RoutedEvent>)_dTypedRoutedEventList[keys.List[i]];

                    for (int j = 0; j < dTypedRoutedEventList.Count; j++)
                    {
                        RoutedEvent routedEvent = dTypedRoutedEventList[j];

                        if (Array.IndexOf(routedEvents, routedEvent) < 0)
                        {
                            routedEvents[destIndex++] = routedEvent;
                        }
                    }
                }

                // Enumerate through all of the RoutedEvents in the Hashtable
                // Requires GlobalLock to access _ownerTypedRoutedEventList
                IDictionaryEnumerator htEnumerator = _ownerTypedRoutedEventList.GetEnumerator();

                while (htEnumerator.MoveNext() == true)
                {
                    FrugalObjectList <RoutedEvent> ownerRoutedEventList = (FrugalObjectList <RoutedEvent>)htEnumerator.Value;

                    for (int j = 0; j < ownerRoutedEventList.Count; j++)
                    {
                        RoutedEvent routedEvent = ownerRoutedEventList[j];

                        if (Array.IndexOf(routedEvents, routedEvent) < 0)
                        {
                            routedEvents[destIndex++] = routedEvent;
                        }
                    }
                }
            }

            return(routedEvents);
        }
コード例 #3
0
        // Register a Class Handler
        // NOTE: Handler Type must be the
        // same as the one specified when
        // registering the corresponding RoutedEvent
        internal static void RegisterClassHandler(
            Type classType,
            RoutedEvent routedEvent,
            Delegate handler,
            bool handledEventsToo)
        {
            Debug.Assert(
                typeof(UIElement).IsAssignableFrom(classType) ||
                typeof(ContentElement).IsAssignableFrom(classType) ||
                typeof(UIElement3D).IsAssignableFrom(classType),
                "Class Handlers can be registered only for UIElement/ContentElement/UIElement3D and their sub types");
            Debug.Assert(routedEvent.IsLegalHandler(handler),
                         "Handler Type mismatch");

            ClassHandlersStore classListenersLists;
            int index;

            // We map the classType to a DType use DTypeMap for storage
            DependencyObjectType dType = DependencyObjectType.FromSystemTypeInternal(classType);

            // Get the updated EventHandlersStore for the given DType
            GetDTypedClassListeners(dType, routedEvent, out classListenersLists, out index);

            // Reuired to update storage
            lock (Synchronized)
            {
                // Add new routed event handler and get the updated set of handlers
                RoutedEventHandlerInfoList updatedClassListeners =
                    classListenersLists.AddToExistingHandlers(index, handler, handledEventsToo);

                // Update Sub Classes
                ItemStructList <DependencyObjectType> keys = _dTypedClassListeners.ActiveDTypes;

                for (int i = 0; i < keys.Count; i++)
                {
                    if (keys.List[i].IsSubclassOf(dType) == true)
                    {
                        classListenersLists = (ClassHandlersStore)_dTypedClassListeners[keys.List[i]];
                        classListenersLists.UpdateSubClassHandlers(routedEvent, updatedClassListeners);
                    }
                }
            }
        }
コード例 #4
0
 // Constructor for ClassHandlersStore
 internal ClassHandlersStore(int size)
 {
     _eventHandlersList = new ItemStructList <ClassHandlers>(size);
 }
コード例 #5
0
        //
        //  This method
        //  1. Adds shared table entries for property values set via Triggers
        //
        private static void ProcessTemplateTriggers(
            TriggerCollection                                           triggers,
            FrameworkTemplate                                           frameworkTemplate,
            ref FrugalStructList<ChildRecord>                           childRecordFromChildIndex,
            ref FrugalStructList<ItemStructMap<TriggerSourceRecord>>    triggerSourceRecordFromChildIndex,
            ref FrugalStructList<ContainerDependent>                    containerDependents,
            ref FrugalStructList<ChildPropertyDependent>                resourceDependents,
            ref ItemStructList<ChildEventDependent>                     eventDependents,
            ref HybridDictionary                                        dataTriggerRecordFromBinding,
            HybridDictionary                                            childIndexFromChildID,
            ref bool                                                    hasInstanceValues,
            ref HybridDictionary                                        triggerActions,
            FrameworkElementFactory                                     templateRoot,
            ref EventHandlersStore                                      eventHandlersStore,
            ref FrugalMap                                               propertyTriggersWithActions,
            ref HybridDictionary                                        dataTriggersWithActions,
            ref bool                                                    hasLoadedChangeHandler)
        {
            if (triggers != null)
            {
                int triggerCount = triggers.Count;
                for (int i = 0; i < triggerCount; i++)
                {
                    TriggerBase triggerBase = triggers[i];

                    Trigger trigger;
                    MultiTrigger multiTrigger;
                    DataTrigger dataTrigger;
                    MultiDataTrigger multiDataTrigger;
                    EventTrigger eventTrigger;

                    DetermineTriggerType( triggerBase, out trigger, out multiTrigger, out dataTrigger, out multiDataTrigger, out eventTrigger );

                    if ( trigger != null || multiTrigger != null||
                        dataTrigger != null || multiDataTrigger != null )
                    {
                        // Update the SourceChildIndex for each of the conditions for this trigger
                        TriggerCondition[] conditions = triggerBase.TriggerConditions;
                        for (int k=0; k<conditions.Length; k++)
                        {
                            conditions[k].SourceChildIndex = StyleHelper.QueryChildIndexFromChildName(conditions[k].SourceName, childIndexFromChildID);
                        }

                        // Set things up to handle Setter values
                        for (int j = 0; j < triggerBase.PropertyValues.Count; j++)
                        {
                            PropertyValue propertyValue = triggerBase.PropertyValues[j];

                            // Check for trigger rules that act on template children
                            if (propertyValue.ChildName == StyleHelper.SelfName)
                            {
                                // "Self" (container) trigger

                                // Track properties on the container that are being driven by
                                // the Template so that they can be invalidated during Template changes
                                StyleHelper.AddContainerDependent(propertyValue.Property, true /*fromVisualTrigger*/, ref containerDependents);
                            }

                            StyleHelper.UpdateTables(ref propertyValue, ref childRecordFromChildIndex,
                                ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref dataTriggerRecordFromBinding,
                                childIndexFromChildID, ref hasInstanceValues);
                        }

                        // Set things up to handle TriggerActions
                        if( triggerBase.HasEnterActions || triggerBase.HasExitActions )
                        {
                            if( trigger != null )
                            {
                                StyleHelper.AddPropertyTriggerWithAction( triggerBase, trigger.Property, ref propertyTriggersWithActions );
                            }
                            else if( multiTrigger != null )
                            {
                                for( int k = 0; k < multiTrigger.Conditions.Count; k++ )
                                {
                                    Condition triggerCondition = multiTrigger.Conditions[k];

                                    StyleHelper.AddPropertyTriggerWithAction( triggerBase, triggerCondition.Property, ref propertyTriggersWithActions );
                                }
                            }
                            else if( dataTrigger != null )
                            {
                                StyleHelper.AddDataTriggerWithAction( triggerBase, dataTrigger.Binding, ref dataTriggersWithActions );
                            }
                            else if( multiDataTrigger != null )
                            {
                                for( int k = 0; k < multiDataTrigger.Conditions.Count; k++ )
                                {
                                    Condition dataCondition = multiDataTrigger.Conditions[k];

                                    StyleHelper.AddDataTriggerWithAction( triggerBase, dataCondition.Binding, ref dataTriggersWithActions );
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.Get(SRID.UnsupportedTriggerInTemplate, triggerBase.GetType().Name));
                            }
                        }
                    }
                    else if( eventTrigger != null )
                    {
                        StyleHelper.ProcessEventTrigger(eventTrigger,
                                                        childIndexFromChildID,
                                                        ref triggerActions,
                                                        ref eventDependents,
                                                        templateRoot,
                                                        frameworkTemplate,
                                                        ref eventHandlersStore,
                                                        ref hasLoadedChangeHandler);
                    }
                    else
                    {
                        throw new InvalidOperationException(SR.Get(SRID.UnsupportedTriggerInTemplate, triggerBase.GetType().Name));
                    }
                }
            }
        }
コード例 #6
0
ファイル: ClassHandlersStore.cs プロジェクト: JianwenSun/cc
 // Constructor for ClassHandlersStore
 internal ClassHandlersStore(int size)
 {
     _eventHandlersList = new ItemStructList<ClassHandlers>(size);
 }
コード例 #7
0
        //
        //  All table datastructures read-lock-free/write-lock
        //  AddEventDependent writes the datastructures, locks set by callers
        //
        //  This method
        //  1. Adds an EventDependent to the EventDependents list. This is used
        //     to lookup events in styles during event routing.
        //
        internal static void AddEventDependent(
            int                                     childIndex,
            EventHandlersStore                      eventHandlersStore,
            ref ItemStructList<ChildEventDependent> eventDependents)
        {
            if (eventHandlersStore != null)
            {
                Debug.Assert(childIndex >= 0);

                ChildEventDependent dependent = new ChildEventDependent();
                dependent.ChildIndex = childIndex;
                dependent.EventHandlersStore = eventHandlersStore;

                eventDependents.Add(ref dependent);
            }
        }
コード例 #8
0
        //+----------------------------------------------------------------------------------------------
        //
        //  ProcessTemplateContentFromFEF
        //
        //  This method walks the FEF tree and builds the shared tables from the property values
        //  in the FEF.
        //
        //  For the Baml templates (non-FEF), see the ProcessTemplateContent routine.
        //
        //+----------------------------------------------------------------------------------------------

        internal static void ProcessTemplateContentFromFEF(
            FrameworkElementFactory                                     factory,
            ref FrugalStructList<ChildRecord>                           childRecordFromChildIndex,
            ref FrugalStructList<ItemStructMap<TriggerSourceRecord>>    triggerSourceRecordFromChildIndex,
            ref FrugalStructList<ChildPropertyDependent>                resourceDependents,
            ref ItemStructList<ChildEventDependent>                     eventDependents,
            ref HybridDictionary                                        dataTriggerRecordFromBinding,
            HybridDictionary                                            childIndexFromChildID,
            ref bool                                                    hasInstanceValues)
        {
            // Process the PropertyValues on the current node
            for (int i = 0; i < factory.PropertyValues.Count; i++)
            {
                PropertyValue propertyValue = factory.PropertyValues[i];
                StyleHelper.UpdateTables(ref propertyValue, ref childRecordFromChildIndex,
                    ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref dataTriggerRecordFromBinding,
                    childIndexFromChildID, ref hasInstanceValues);
            }

            // Add an entry in the EventDependents list for
            // the current TemplateNode's EventHandlersStore.
            StyleHelper.AddEventDependent(factory._childIndex, factory.EventHandlersStore,
                ref eventDependents);

            // Traverse the children of this TemplateNode
            factory = factory.FirstChild;
            while (factory != null)
            {
                ProcessTemplateContentFromFEF(factory, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref resourceDependents,
                    ref eventDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues);

                factory = factory.NextSibling;
            }
        }
コード例 #9
0
        //  ===========================================================================
        //  These methods are invoked when a Style/Template is Sealed
        //  ===========================================================================

        #region WriteMethods

        //
        //  This method
        //  1. Seals a template
        //
        internal static void SealTemplate(
            FrameworkTemplate                                           frameworkTemplate,
            ref bool                                                    isSealed,
            FrameworkElementFactory                                     templateRoot,
            TriggerCollection                                           triggers,
            ResourceDictionary                                          resources,
            HybridDictionary                                            childIndexFromChildID,
            ref FrugalStructList<ChildRecord>                           childRecordFromChildIndex,
            ref FrugalStructList<ItemStructMap<TriggerSourceRecord>>    triggerSourceRecordFromChildIndex,
            ref FrugalStructList<ContainerDependent>                    containerDependents,
            ref FrugalStructList<ChildPropertyDependent>                resourceDependents,
            ref ItemStructList<ChildEventDependent>                     eventDependents,
            ref HybridDictionary                                        triggerActions,
            ref HybridDictionary                                        dataTriggerRecordFromBinding,
            ref bool                                                    hasInstanceValues,
            ref EventHandlersStore                                      eventHandlersStore)
        {
            Debug.Assert(frameworkTemplate != null );

            // This template has already been sealed.
            // There is no more to do.
            if (isSealed)
            {
                return;
            }

            // Seal template nodes (if exists)


            if (frameworkTemplate != null)
            {
                frameworkTemplate.ProcessTemplateBeforeSeal();
            }


            if (templateRoot != null)
            {
                Debug.Assert( !frameworkTemplate.HasXamlNodeContent );

                // Seal the template

                Debug.Assert(frameworkTemplate != null);
                //frameworkTemplate.ProcessTemplateBeforeSeal();
                templateRoot.Seal(frameworkTemplate);
            }

            // Seal triggers
            if (triggers != null)
            {
                triggers.Seal();
            }

            // Seal Resource Dictionary
            if (resources != null)
            {
                resources.IsReadOnly = true;
            }

            //  Build shared tables

            if (templateRoot != null)
            {
                // This is a FEF-style template.  Process the root node, and it will
                // recurse through the rest of the FEF tree.

                StyleHelper.ProcessTemplateContentFromFEF(
                                templateRoot,
                                ref childRecordFromChildIndex,
                                ref triggerSourceRecordFromChildIndex,
                                ref resourceDependents,
                                ref eventDependents,
                                ref dataTriggerRecordFromBinding,
                                childIndexFromChildID,
                                ref hasInstanceValues);
            }

            // Process Triggers. (Trigger PropertyValues are inserted
            // last into the Style/Template GetValue chain because they
            // are the highest priority)

            bool hasHandler = false;

            Debug.Assert( frameworkTemplate != null );

            StyleHelper.ProcessTemplateTriggers(
                triggers,
                frameworkTemplate,
                ref childRecordFromChildIndex,
                ref triggerSourceRecordFromChildIndex, ref containerDependents, ref resourceDependents, ref eventDependents,
                ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues,
                ref triggerActions, templateRoot, ref eventHandlersStore,
                ref frameworkTemplate.PropertyTriggersWithActions,
                ref frameworkTemplate.DataTriggersWithActions,
                ref hasHandler );

            frameworkTemplate.HasLoadedChangeHandler = hasHandler;

            frameworkTemplate.SetResourceReferenceState();

            // All done, seal self and call it a day.
            isSealed = true;

            // Remove thread affinity so it can be accessed across threads
            frameworkTemplate.DetachFromDispatcher();

            // Check if the template has the Template property set on the container via its visual triggers.
            // It is an error to specify the TemplateProperty in your own Template.
            if (StyleHelper.IsSetOnContainer(Control.TemplateProperty, ref containerDependents, true) ||
                StyleHelper.IsSetOnContainer(ContentPresenter.TemplateProperty, ref containerDependents, true))
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, Control.TemplateProperty.Name));
            }

            // Check if the template has the Style property set on the container via its visual triggers.
            // It is an error to specify the StyleProperty in your own Template.
            if (StyleHelper.IsSetOnContainer(FrameworkElement.StyleProperty, ref containerDependents, true))
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.StyleProperty.Name));
            }

            // Check if the template has the DefaultStyleKey property set on the container via its visual triggers.
            // It is an error to specify the DefaultStyleKeyProperty in your own Template.
            if (StyleHelper.IsSetOnContainer(FrameworkElement.DefaultStyleKeyProperty, ref containerDependents, true))
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.DefaultStyleKeyProperty.Name));
            }

            // Check if the template has the OverridesDefaultStyle property set on the container via its visual triggers.
            // It is an error to specify the OverridesDefaultStyleProperty in your own Template.
            if (StyleHelper.IsSetOnContainer(FrameworkElement.OverridesDefaultStyleProperty, ref containerDependents, true))
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.OverridesDefaultStyleProperty.Name));
            }

            // Check if the template has the Name property set on the container via its visual triggers.
            // It is an error to specify the Name in your own Template.
            if (StyleHelper.IsSetOnContainer(FrameworkElement.NameProperty, ref containerDependents, true))
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.NameProperty.Name));
            }
        }
コード例 #10
0
        //  ===========================================================================
        //  These methods are used to query Style/Template
        //  eventhandlers during event routing
        //  ===========================================================================

        #region ReadEvents

        //
        //  This method
        //  Gets the handlers of a template child
        //  (Index is '0' when the styled container is asking)
        //
        internal static RoutedEventHandlerInfo[] GetChildRoutedEventHandlers(
            int                                     childIndex,
            RoutedEvent                           routedEvent,
            ref ItemStructList<ChildEventDependent> eventDependents)
        {
            Debug.Assert(routedEvent != null);

            if (childIndex > 0)
            {
                // Find the EventHandlersStore that matches the given childIndex
                EventHandlersStore eventHandlersStore = null;
                for (int i=0; i<eventDependents.Count; i++)
                {
                    if (eventDependents.List[i].ChildIndex == childIndex)
                    {
                        eventHandlersStore = eventDependents.List[i].EventHandlersStore;
                        break;
                    }
                }

                if (eventHandlersStore != null)
                {
                    return eventHandlersStore.GetRoutedEventHandlers(routedEvent);
                }
            }

            return null;
        }
コード例 #11
0
        //
        //  This method
        //  1. Computes the property value given the ChildLookupValue list for it
        //
        private static object GetChildValueHelper(
            UncommonField<HybridDictionary[]>       dataField,
            ref ItemStructList<ChildValueLookup>    valueLookupList,
            DependencyProperty                      dp,
            DependencyObject                        container,
            FrameworkObject                         child,
            int                                     childIndex,
            bool                                    styleLookup,
            ref EffectiveValueEntry                 entry,
            out ValueLookupType                     sourceType,
            FrameworkElementFactory                 templateRoot)
        {
            Debug.Assert(child.IsValid, "child should either be an FE or an FCE");

            object value = DependencyProperty.UnsetValue;
            sourceType = ValueLookupType.Simple;

            // Walk list backwards since highest priority lookup items are inserted last
            for (int i = valueLookupList.Count - 1; i >= 0; i--)
            {
                sourceType = valueLookupList.List[i].LookupType;

                // Lookup logic is determined by lookup type. "Trigger"
                // is misleading right now because today it's also being used
                // for Storyboard timeline lookups.
                switch (valueLookupList.List[i].LookupType)
                {
                case ValueLookupType.Simple:
                    {
                        // Simple value
                        value = valueLookupList.List[i].Value;
                    }
                    break;

                case ValueLookupType.Trigger:
                case ValueLookupType.PropertyTriggerResource:
                case ValueLookupType.DataTrigger:
                case ValueLookupType.DataTriggerResource:
                    {
                        // Conditional value based on Container state
                        bool triggerMatch = true;

                        if( valueLookupList.List[i].Conditions != null )
                        {
                            // Check whether the trigger applies.  All conditions must match,
                            // so the loop can terminate as soon as it finds a condition
                            // that doesn't match.
                            for (int j = 0; triggerMatch && j < valueLookupList.List[i].Conditions.Length; j++)
                            {
                                object state;

                                switch (valueLookupList.List[i].LookupType)
                                {
                                case ValueLookupType.Trigger:
                                case ValueLookupType.PropertyTriggerResource:
                                    // Find the source node
                                    DependencyObject sourceNode;
                                    int sourceChildIndex = valueLookupList.List[i].Conditions[j].SourceChildIndex;
                                    if (sourceChildIndex == 0)
                                    {
                                        sourceNode = container;
                                    }
                                    else
                                    {
                                        sourceNode = StyleHelper.GetChild(container, sourceChildIndex);
                                    }

                                    // Note that the sourceNode could be null when the source
                                    // property for this trigger is on a node that hasn't been
                                    // instantiated yet.
                                    DependencyProperty sourceProperty = valueLookupList.List[i].Conditions[j].Property;
                                    if (sourceNode != null)
                                    {
                                        state = sourceNode.GetValue(sourceProperty);
                                    }
                                    else
                                    {
                                        Type sourceNodeType;

                                        if( templateRoot != null )
                                        {
                                            sourceNodeType = FindFEF(templateRoot, sourceChildIndex).Type;
                                        }
                                        else
                                        {
                                            sourceNodeType = (container as FrameworkElement).TemplateInternal.ChildTypeFromChildIndex[sourceChildIndex];
                                        }

                                        state = sourceProperty.GetDefaultValue(sourceNodeType);
                                    }

                                    triggerMatch = valueLookupList.List[i].Conditions[j].Match(state);

                                    break;

                                case ValueLookupType.DataTrigger:
                                case ValueLookupType.DataTriggerResource:
                                default:    // this cannot happen - but make the compiler happy

                                    state = GetDataTriggerValue(dataField, container, valueLookupList.List[i].Conditions[j].Binding);
                                    triggerMatch = valueLookupList.List[i].Conditions[j].ConvertAndMatch(state);

                                    break;
                                }
                            }
                        }

                        if (triggerMatch)
                        {
                            // Conditionals matched, use the value

                            if (valueLookupList.List[i].LookupType == ValueLookupType.PropertyTriggerResource ||
                                valueLookupList.List[i].LookupType == ValueLookupType.DataTriggerResource)
                            {
                                // Resource lookup
                                object source;
                                value = FrameworkElement.FindResourceInternal(child.FE,
                                                                              child.FCE,
                                                                              dp,
                                                                              valueLookupList.List[i].Value,  // resourceKey
                                                                              null,  // unlinkedParent
                                                                              true,  // allowDeferredResourceReference
                                                                              false, // mustReturnDeferredResourceReference
                                                                              null,  // boundaryElement
                                                                              false, // disableThrowOnResourceNotFound
                                                                              out source);

                                // Try to freeze the value
                                SealIfSealable(value);
                            }
                            else
                            {
                                value = valueLookupList.List[i].Value;
                            }
                        }
                    }
                    break;

                case ValueLookupType.TemplateBinding:
                    {
                        TemplateBindingExtension templateBinding = (TemplateBindingExtension)valueLookupList.List[i].Value;
                        DependencyProperty sourceProperty = templateBinding.Property;

                        // Direct binding of Child property to Container
                        value = container.GetValue(sourceProperty);

                        // Apply the converter, if any
                        if (templateBinding.Converter != null)
                        {
                            DependencyProperty targetProperty = valueLookupList.List[i].Property;
                            System.Globalization.CultureInfo culture = child.Language.GetCompatibleCulture();

                            value = templateBinding.Converter.Convert(
                                                value,
                                                targetProperty.PropertyType,
                                                templateBinding.ConverterParameter,
                                                culture);
                        }

                        // if the binding returns an invalid value, fallback to default value
                        if ((value != DependencyProperty.UnsetValue) && !dp.IsValidValue(value))
                        {
                            value = DependencyProperty.UnsetValue;
                        }
                    }
                    break;

                case ValueLookupType.Resource:
                    {
                        // Resource lookup
                        object source;
                        value = FrameworkElement.FindResourceInternal(
                                        child.FE,
                                        child.FCE,
                                        dp,
                                        valueLookupList.List[i].Value,  // resourceKey
                                        null,  // unlinkedParent
                                        true,  // allowDeferredResourceReference
                                        false, // mustReturnDeferredResourceReference
                                        null,  // boundaryElement
                                        false, // disableThrowOnResourceNotFound
                                        out source);

                        // Try to freeze the value
                        SealIfSealable(value);
                    }
                    break;
                }

                // See if value needs per-instance storage
                if (value != DependencyProperty.UnsetValue)
                {
                    entry.Value = value;
                    // When the value requires per-instance storage (and comes from this style),
                    // get the real value from per-instance data.
                    switch (valueLookupList.List[i].LookupType)
                    {
                    case ValueLookupType.Simple:
                    case ValueLookupType.Trigger:
                    case ValueLookupType.DataTrigger:
                        {
                            MarkupExtension me;
                            Freezable freezable;

                            if ((me = value as MarkupExtension) != null)
                            {
                                value = GetInstanceValue(
                                                dataField,
                                                container,
                                                child.FE,
                                                child.FCE,
                                                childIndex,
                                                valueLookupList.List[i].Property,
                                                i,
                                                ref entry);
                            }
                            else if ((freezable = value as Freezable) != null && !freezable.IsFrozen)
                            {
                                value = GetInstanceValue(
                                                dataField,
                                                container,
                                                child.FE,
                                                child.FCE,
                                                childIndex,
                                                valueLookupList.List[i].Property,
                                                i,
                                                ref entry);
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }

                if (value != DependencyProperty.UnsetValue)
                {
                    // Found a value, break out of the for() loop.
                    break;
                }
            }

            return value;
        }
コード例 #12
0
        //
        //  This method
        //  1. Adds or removes per-instance state on the container/child (push model)
        //  2. Processes values that need per-instance storage
        //
        private static void ProcessInstanceValuesHelper(
            ref ItemStructList<ChildValueLookup> valueLookupList,
            DependencyObject                     target,
            int                                  childIndex,
            HybridDictionary                     instanceValues,
            bool                                 apply)
        {
            // update all properties whose value needs per-instance storage
            for (int i = valueLookupList.Count - 1;  i >= 0;  --i)
            {
                switch (valueLookupList.List[i].LookupType)
                {
                case ValueLookupType.Simple:
                case ValueLookupType.Trigger:
                case ValueLookupType.DataTrigger:
                    Freezable freezable;

                    DependencyProperty dp = valueLookupList.List[i].Property;
                    object o = valueLookupList.List[i].Value;

                    if (o is MarkupExtension)
                    {
                        ProcessInstanceValue(target, childIndex, instanceValues, dp, i, apply);
                    }
                    else if ((freezable = o as Freezable) != null)
                    {
                        if (freezable.CheckAccess())
                        {
                            if (!freezable.IsFrozen)
                            {
                                ProcessInstanceValue(target, childIndex, instanceValues, dp, i, apply);
                            }
                        }
                        else
                        {
                            Debug.Assert(!freezable.CanFreeze, "If a freezable could have been frozen it would have been done by now.");
                            throw new InvalidOperationException(SR.Get(SRID.CrossThreadAccessOfUnshareableFreezable, freezable.GetType().FullName));
                        }
                    }

                    break;
                }
            }
        }
コード例 #13
0
        //+---------------------------------------------------------------------------------------
        //
        //  AddDelegateToFireTrigger
        //
        //  Add the EventTriggerHandlerOnChild to listen for an event, like the above overload
        //  except this is for baml-style templates, rather than FEF-style.
        //
        //+---------------------------------------------------------------------------------------

        private static void AddDelegateToFireTrigger(
            RoutedEvent                             routedEvent,
            int                                     childIndex,
            ref ItemStructList<ChildEventDependent> eventDependents,
            ref EventHandlersStore                  eventHandlersStore)
        {
            Debug.Assert( childIndex != 0 ); // This should go to the other AddDelegateToFireTrigger overload


            if (eventHandlersStore == null)
            {
                eventHandlersStore = new EventHandlersStore();
            }

            StyleHelper.AddEventDependent( childIndex,
                                           eventHandlersStore,
                                           ref eventDependents );
            eventHandlersStore.AddRoutedEventHandler(routedEvent, StyleHelper.EventTriggerHandlerOnChild, false/* HandledEventsToo */);

        }
コード例 #14
0
        //
        //  This method
        //  1. Adds a delegate that will get called during event routing and
        //     will allow us to invoke the TriggerActions
        //
        private static void AddDelegateToFireTrigger(
            RoutedEvent                             routedEvent,
            int                                     childIndex,
            FrameworkElementFactory                 templateRoot,
            FrameworkElementFactory                 childFef,
            ref ItemStructList<ChildEventDependent> eventDependents,
            ref EventHandlersStore                  eventHandlersStore)
        {
            if (childIndex == 0)
            {
                if (eventHandlersStore == null)
                {
                    eventHandlersStore = new EventHandlersStore();

                    // Add an entry in the EventDependents list for
                    // the TargetType's EventHandlersStore. Notice
                    // that the childIndex is 0.
                    StyleHelper.AddEventDependent(0, eventHandlersStore, ref eventDependents);
                }
                eventHandlersStore.AddRoutedEventHandler(routedEvent, StyleHelper.EventTriggerHandlerOnContainer, false/* HandledEventsToo */);
            }
            else
            {
                //FrameworkElementFactory fef = StyleHelper.FindFEF(templateRoot, childIndex);
                if (childFef.EventHandlersStore == null)
                {
                    childFef.EventHandlersStore = new EventHandlersStore();

                    // Add an entry in the EventDependents list for
                    // the current FEF's EventHandlersStore.
                    StyleHelper.AddEventDependent(childIndex, childFef.EventHandlersStore, ref eventDependents);
                }
                childFef.EventHandlersStore.AddRoutedEventHandler(routedEvent, StyleHelper.EventTriggerHandlerOnChild, false/* HandledEventsToo */);
            }
        }
コード例 #15
0
        //
        //  This method
        //  1. Adds the trigger information to the data structure that will be
        //     used when it's time to add the delegate to the event route.
        //
        internal static void ProcessEventTrigger (
            EventTrigger                            eventTrigger,
            HybridDictionary                        childIndexFromChildName,
            ref HybridDictionary                    triggerActions,
            ref ItemStructList<ChildEventDependent> eventDependents,
            FrameworkElementFactory                 templateRoot,
            FrameworkTemplate                       frameworkTemplate,
            ref EventHandlersStore                  eventHandlersStore,
            ref bool                                hasLoadedChangeHandler)
        {
            if( eventTrigger == null )
            {
                return;
            }

            // The list of actions associated with the event of this EventTrigger.
            List<TriggerAction> actionsList = null;
            bool                actionsListExisted = true;
            bool                actionsListChanged = false;
            TriggerAction       action = null;

            FrameworkElementFactory childFef = null;

            // Find a ChildID for the EventTrigger.
            if( eventTrigger.SourceName == null )
            {
                eventTrigger.TriggerChildIndex = 0;
            }
            else
            {
                int childIndex = StyleHelper.QueryChildIndexFromChildName(eventTrigger.SourceName, childIndexFromChildName);

                if( childIndex == -1 )
                {
                    throw new InvalidOperationException(SR.Get(SRID.EventTriggerTargetNameUnresolvable, eventTrigger.SourceName));
                }

                eventTrigger.TriggerChildIndex = childIndex;
            }

            // We have at least one EventTrigger - will need triggerActions
            // if it doesn't already exist
            if (triggerActions == null)
            {
                triggerActions = new HybridDictionary();
            }
            else
            {
                actionsList = triggerActions[eventTrigger.RoutedEvent] as List<TriggerAction>;
            }

            // Set up TriggerAction list if one doesn't already exist
            if (actionsList == null)
            {
                actionsListExisted = false;
                actionsList = new List<TriggerAction>();
            }

            for (int i = 0; i < eventTrigger.Actions.Count; i++)
            {
                action = eventTrigger.Actions[i];

                // Any reason we shouldn't use this TriggerAction?  Check here.
                if( false /* No reason not to use it right now */ )
                {
                    // continue;
                }

                // Looks good, add to list.
                Debug.Assert(action.IsSealed, "TriggerAction should have already been sealed by this point.");
                actionsList.Add(action);
                actionsListChanged = true;
            }

            if (actionsListChanged && !actionsListExisted)
            {
                triggerActions[eventTrigger.RoutedEvent] = actionsList;
            }


            // Add a special delegate to listen for this event and
            // fire the trigger.

            if( templateRoot != null || eventTrigger.TriggerChildIndex == 0 )
            {
                // This is a FEF-style template, or the trigger is keying off of
                // the templated parent.

                // Get the FEF that is referenced by this trigger.

                if (eventTrigger.TriggerChildIndex != 0)
                {
                    childFef = StyleHelper.FindFEF(templateRoot, eventTrigger.TriggerChildIndex);
                }

                // If this trigger needs the loaded/unloaded events, set the optimization
                // flag.

                if (  (eventTrigger.RoutedEvent == FrameworkElement.LoadedEvent)
                    ||(eventTrigger.RoutedEvent == FrameworkElement.UnloadedEvent))
                {
                    if (eventTrigger.TriggerChildIndex == 0)
                    {
                        // Mark the template to show it has a loaded or unloaded handler

                        hasLoadedChangeHandler  = true;
                    }
                    else
                    {
                        // Mark the FEF to show it has a loaded or unloaded handler

                        childFef.HasLoadedChangeHandler  = true;
                    }
                }


                // Add a delegate that'll come back and fire these actions.
                //  This information will be used by FrameworkElement.AddStyleHandlersToEventRoute

                StyleHelper.AddDelegateToFireTrigger(eventTrigger.RoutedEvent,
                                                     eventTrigger.TriggerChildIndex,
                                                     templateRoot,
                                                     childFef,
                                                     ref eventDependents,
                                                     ref eventHandlersStore);
            }
            else
            {
                // This is a baml-style template.

                // If this trigger needs the loaded/unloaded events, set the optimization
                // flag.

                if (eventTrigger.RoutedEvent == FrameworkElement.LoadedEvent
                    ||
                    eventTrigger.RoutedEvent == FrameworkElement.UnloadedEvent )
                {
                    FrameworkTemplate.TemplateChildLoadedFlags templateChildLoadedFlags
                        = frameworkTemplate._TemplateChildLoadedDictionary[ eventTrigger.TriggerChildIndex ] as FrameworkTemplate.TemplateChildLoadedFlags;

                    if( templateChildLoadedFlags == null )
                    {
                        templateChildLoadedFlags = new FrameworkTemplate.TemplateChildLoadedFlags();
                        frameworkTemplate._TemplateChildLoadedDictionary[ eventTrigger.TriggerChildIndex ] = templateChildLoadedFlags;
                    }

                    if( eventTrigger.RoutedEvent == FrameworkElement.LoadedEvent )
                    {
                        templateChildLoadedFlags.HasLoadedChangedHandler = true;
                    }
                    else
                    {
                        templateChildLoadedFlags.HasUnloadedChangedHandler = true;
                    }
                }


                // Add a delegate that'll come back and fire these actions.

                StyleHelper.AddDelegateToFireTrigger(eventTrigger.RoutedEvent,
                                                     eventTrigger.TriggerChildIndex,
                                                     ref eventDependents,
                                                     ref eventHandlersStore);
            }
        }