/// <summary> /// Adds a routed event handler for the given /// RoutedEvent to the store /// </summary> public void AddRoutedEventHandler( RoutedEvent routedEvent, Delegate handler, bool handledEventsToo) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } // Create a new RoutedEventHandler RoutedEventHandlerInfo routedEventHandlerInfo = new RoutedEventHandlerInfo(handler, handledEventsToo); // Get the entry corresponding to the given RoutedEvent FrugalObjectList <RoutedEventHandlerInfo> handlers = (FrugalObjectList <RoutedEventHandlerInfo>) this[routedEvent]; if (handlers == null) { _entries[routedEvent.GlobalIndex] = handlers = new FrugalObjectList <RoutedEventHandlerInfo>(1); } // Add the RoutedEventHandlerInfo to the list handlers.Add(routedEventHandlerInfo); }
/// <summary> /// Add a routed event handler to all instances of a /// particular type inclusive of its sub-class types /// </summary> /// <remarks> /// The handlers added thus are also known as /// an class handlers <para/> /// <para/> /// /// Class handlers are invoked before the /// instance handlers. Also see /// <see cref="UIElement.AddHandler(RoutedEvent, Delegate)"/> <para/> /// Sub-class class handlers are invoked before /// the super-class class handlers <para/> /// <para/> /// /// Input parameters classType, <see cref="RoutedEvent"/> /// and handler cannot be null <para/> /// handledEventsToo input parameter when false means /// that listener does not care about already handled events. /// Hence the handler will not be invoked on the target if /// the RoutedEvent has already been /// <see cref="RoutedEventArgs.Handled"/> <para/> /// handledEventsToo input parameter when true means /// that the listener wants to hear about all events even if /// they have already been handled. Hence the handler will /// be invoked irrespective of the event being /// <see cref="RoutedEventArgs.Handled"/> /// </remarks> /// <param name="classType"> /// Target object type on which the handler will be invoked /// when the RoutedEvent is raised /// </param> /// <param name="routedEvent"> /// <see cref="RoutedEvent"/> for which the handler /// is attached /// </param> /// <param name="handler"> /// The handler that will be invoked on the target object /// when the RoutedEvent is raised /// </param> /// <param name="handledEventsToo"> /// Flag indicating whether or not the listener wants to /// hear about events that have already been handled /// </param> /// <ExternalAPI/> public static void RegisterClassHandler( Type classType, RoutedEvent routedEvent, Delegate handler, bool handledEventsToo) { if (classType == null) { throw new ArgumentNullException("classType"); } if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!typeof(UIElement).IsAssignableFrom(classType) && !typeof(ContentElement).IsAssignableFrom(classType) && !typeof(UIElement3D).IsAssignableFrom(classType)) { throw new ArgumentException(SR.Get(SRID.ClassTypeIllegal)); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } GlobalEventManager.RegisterClassHandler(classType, routedEvent, handler, handledEventsToo); }
// 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); } } } }
// 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); } } } }
/// <summary> /// Removes an instance of the specified /// routed event handler for the given /// RoutedEvent from the store /// </summary> /// <remarks> /// NOTE: This method does nothing if no /// matching handler instances are found /// in the store /// </remarks> public void RemoveRoutedEventHandler(RoutedEvent routedEvent, Delegate handler) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } // Get the entry corresponding to the given RoutedEvent FrugalObjectList <RoutedEventHandlerInfo> handlers = (FrugalObjectList <RoutedEventHandlerInfo>) this[routedEvent]; if (handlers != null && handlers.Count > 0) { if ((handlers.Count == 1) && (handlers[0].Handler == handler)) { // this is the only handler for this event and it's being removed // reclaim space in underlying FrugalMap by setting value to // DependencyProperty.UnsetValue _entries[routedEvent.GlobalIndex] = DependencyProperty.UnsetValue; } else { // When a matching instance is found remove it for (int i = 0; i < handlers.Count; i++) { if (handlers[i].Handler == handler) { handlers.RemoveAt(i); break; } } } } }
/// <summary> /// Removes all instances of the specified routed /// event handler for this object instance /// </summary> /// <remarks> /// The handler removed thus is also known as /// an instance handler <para/> /// <para/> /// /// NOTE: This method does nothing if there were /// no handlers registered with the matching /// criteria <para/> /// <para/> /// /// Input parameters <see cref="RoutedEvent"/> /// and handler cannot be null <para/> /// This method ignores the handledEventsToo criterion /// </remarks> /// <param name="routedEvent"> /// <see cref="RoutedEvent"/> for which the handler /// is attached /// </param> /// <param name="handler"> /// The handler for this object instance to be removed /// </param> public void RemoveHandler(RoutedEvent routedEvent, Delegate handler) { // VerifyAccess(); if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } EventHandlersStore store = EventHandlersStore; if (store != null) { store.RemoveRoutedEventHandler(routedEvent, handler); OnRemoveHandler (routedEvent, handler); if (store.Count == 0) { // last event handler was removed -- throw away underlying EventHandlersStore EventHandlersStoreField.ClearValue(this); WriteFlag(CoreFlags.ExistsEventHandlersStore, false); } } }
/// <summary> /// Adds a routed event handler for the particular /// <see cref="RoutedEvent"/> /// </summary> /// <remarks> /// The handler added thus is also known as /// an instance handler <para/> /// <para/> /// /// NOTE: It is not an error to add a handler twice /// (handler will simply be called twice) <para/> /// <para/> /// /// Input parameters <see cref="RoutedEvent"/> /// and handler cannot be null <para/> /// handledEventsToo input parameter when false means /// that listener does not care about already handled events. /// Hence the handler will not be invoked on the target if /// the RoutedEvent has already been /// <see cref="RoutedEventArgs.Handled"/> <para/> /// handledEventsToo input parameter when true means /// that the listener wants to hear about all events even if /// they have already been handled. Hence the handler will /// be invoked irrespective of the event being /// <see cref="RoutedEventArgs.Handled"/> /// </remarks> /// <param name="routedEvent"> /// <see cref="RoutedEvent"/> for which the handler /// is attached /// </param> /// <param name="handler"> /// The handler that will be invoked on this object /// when the RoutedEvent is raised /// </param> /// <param name="handledEventsToo"> /// Flag indicating whether or not the listener wants to /// hear about events that have already been handled /// </param> public void AddHandler( RoutedEvent routedEvent, Delegate handler, bool handledEventsToo) { // VerifyAccess(); if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } EnsureEventHandlersStore(); EventHandlersStore.AddRoutedEventHandler(routedEvent, handler, handledEventsToo); OnAddHandler (routedEvent, handler); }
/// <summary> /// Removes an instance of the specified /// routed event handler for the given /// RoutedEvent from the store /// </summary> /// <remarks> /// NOTE: This method does nothing if no /// matching handler instances are found /// in the store /// </remarks> public void RemoveRoutedEventHandler(RoutedEvent routedEvent, Delegate handler) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } // Get the entry corresponding to the given RoutedEvent FrugalObjectList<RoutedEventHandlerInfo> handlers = (FrugalObjectList<RoutedEventHandlerInfo>)this[routedEvent]; if (handlers != null && handlers.Count > 0) { if ((handlers.Count == 1) && (handlers[0].Handler == handler)) { // this is the only handler for this event and it's being removed // reclaim space in underlying FrugalMap by setting value to // DependencyProperty.UnsetValue _entries[routedEvent.GlobalIndex] = DependencyProperty.UnsetValue; } else { // When a matching instance is found remove it for (int i = 0; i < handlers.Count; i++) { if (handlers[i].Handler == handler) { handlers.RemoveAt(i); break; } } } } }
/// <summary> /// Adds a routed event handler for the given /// RoutedEvent to the store /// </summary> public void AddRoutedEventHandler( RoutedEvent routedEvent, Delegate handler, bool handledEventsToo) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } if (!routedEvent.IsLegalHandler(handler)) { throw new ArgumentException(SR.Get(SRID.HandlerTypeIllegal)); } // Create a new RoutedEventHandler RoutedEventHandlerInfo routedEventHandlerInfo = new RoutedEventHandlerInfo(handler, handledEventsToo); // Get the entry corresponding to the given RoutedEvent FrugalObjectList<RoutedEventHandlerInfo> handlers = (FrugalObjectList<RoutedEventHandlerInfo>)this[routedEvent]; if (handlers == null) { _entries[routedEvent.GlobalIndex] = handlers = new FrugalObjectList<RoutedEventHandlerInfo>(1); } // Add the RoutedEventHandlerInfo to the list handlers.Add(routedEventHandlerInfo); }