Exemplo n.º 1
0
        // Helper method to retrieve and fire Clr Event handlers for DependencyPropertyChanged event
        private void RaiseDependencyPropertyChanged(EventPrivateKey key, DependencyPropertyChangedEventArgs args)
        {
            EventHandlersStore store = EventHandlersStore;

            if (store != null)
            {
                Delegate handler = store.Get(key);
                if (handler != null)
                {
                    ((DependencyPropertyChangedEventHandler)handler)(this, args);
                }
            }
        }
Exemplo n.º 2
0
        private void RaiseMouseButtonEvent(EventPrivateKey key, MouseButtonEventArgs e)
        {
            EventHandlersStore store = EventHandlersStore;

            if (store != null)
            {
                Delegate handler = store.Get(key);
                if (handler != null)
                {
                    ((MouseButtonEventHandler)handler)(this, e);
                }
            }
        }
Exemplo n.º 3
0
        // Helper method to retrieve and fire the InheritedPropertyChanged event
        internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info)
        {
            EventHandlersStore store = EventHandlersStore;

            if (store != null)
            {
                Delegate handler = store.Get(FrameworkElement.InheritedPropertyChangedKey);
                if (handler != null)
                {
                    InheritedPropertyChangedEventArgs args = new InheritedPropertyChangedEventArgs(ref info);
                    ((InheritedPropertyChangedEventHandler)handler)(this, args);
                }
            }
        }
Exemplo n.º 4
0
        // 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<System.Windows.PropertyValue>(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); 
        }
 /// <summary>
 /// Copy constructor for EventHandlersStore
 /// </summary>
 public EventHandlersStore(EventHandlersStore source)
 {
     _entries = source._entries;
 }
Exemplo n.º 6
0
        // 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 <System.Windows.PropertyValue>(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);
        }
        /// <summary>
        ///     Add an event handler for the given routed event. This action applies to the instances created by this factory
        /// </summary>
        public void AddHandler(RoutedEvent routedEvent, Delegate handler, bool handledEventsToo)
        {
            if (_sealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "FrameworkElementFactory"));
            }

            if (routedEvent == null)
            {
                throw new ArgumentNullException("routedEvent");
            }

            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }

            if (handler.GetType() != routedEvent.HandlerType)
            {
                throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal));
            }

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

            _eventHandlersStore.AddRoutedEventHandler(routedEvent, handler, handledEventsToo);

            // Keep track of whether we're listening to the loaded or unloaded events;
            // if so, we have to trigger a listener in the FE/FCE (as a performance
            // optimization).

            if (  (routedEvent == FrameworkElement.LoadedEvent)
                ||(routedEvent == FrameworkElement.UnloadedEvent))
            {
                HasLoadedChangeHandler = true;
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Copy constructor for EventHandlersStore 
 /// </summary>
 public EventHandlersStore(EventHandlersStore source)
 {
     _entries = source._entries; 
 }
Exemplo n.º 9
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);
            }
        }
Exemplo n.º 10
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));
                    }
                }
            }
        }
Exemplo n.º 11
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));
            }
        }
Exemplo n.º 12
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 */);

        }
Exemplo n.º 13
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 */);
            }
        }
Exemplo n.º 14
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);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Adds a delegate to the list of event handlers on this object.
        /// </summary>
        /// <param name="key">
        /// A unique identifier for the event handler.
        /// </param>
        /// <param name="handler">The delegate to add.</param>
        private void AddEventHandler(EventPrivateKey key, Delegate handler)
        {
            WritePreamble();

            EventHandlersStore store = EventHandlersStoreField.GetValue(this);

            if (store == null)
            {
                store = new EventHandlersStore();
                EventHandlersStoreField.SetValue(this, store);
            }

            store.Add(key, handler);
            WritePostscript();
        }