/// <summary> /// Adds a handler to the specified routed event. /// </summary> /// <param name="evt">A <see cref="RoutedEvent"/> value which identifies the event to which to add a handler.</param> /// <param name="handler">A delegate which represents the handler to add to the specified routed event.</param> /// <param name="handledEventsToo">A value indicating whether the handler should receive events which have already been handled by other handlers.</param> public void Add(RoutedEvent evt, Delegate handler, Boolean handledEventsToo) { Contract.Require(evt, nameof(evt)); Contract.Require(handler, nameof(handler)); if (evt.DelegateType != handler.GetType()) { throw new ArgumentException(PresentationStrings.HandlerTypeMismatch.Format(handler.GetType().Name, evt.DelegateType.Name), "handler"); } lock (routedEventDelegates) { List <RoutedEventHandlerMetadata> events; if (!routedEventDelegates.TryGetValue(evt.ID, out events)) { events = new List <RoutedEventHandlerMetadata>(); routedEventDelegates[evt.ID] = events; } var routedEventInfo = new RoutedEventHandlerMetadata(handler, 0, 0, handledEventsToo); lock (events) { events.Add(routedEventInfo); } } }
/// <summary> /// Adds a class handler to the manager. /// </summary> /// <param name="classType">The type for which the handler is defined; must be a supertype of the manager's owner type.</param> /// <param name="handler">A delegate which represents the class handler to add to the type.</param> /// <param name="handledEventsToo">A value indicating whether the handler should receive events which have already been handled by other handlers.</param> public void AddHandler(Type classType, Delegate handler, Boolean handledEventsToo) { if (classType != this.ownerType && !this.ownerType.IsSubclassOf(classType)) { throw new ArgumentException(PresentationStrings.ClassTypeMustBeSubclassOfOwnerType.Format(classType.Name, ownerType.Name)); } if (routedEvent.DelegateType != handler.GetType()) { throw new ArgumentException(PresentationStrings.HandlerTypeMismatch.Format(handler.Method.Name, routedEvent.DelegateType.Name), "handler"); } lock (handlers) { var ordinalByType = (short)0; var ordinalWithinType = ordinal++; var currentType = this.ownerType; while (currentType != classType) { ordinalByType++; currentType = currentType.BaseType; } var metadata = new RoutedEventHandlerMetadata(handler, ordinalByType, ordinalWithinType, handledEventsToo); handlers.Add(metadata); if (!sortSuspended) { Sort(); } } }
/// <summary> /// Gets the next event handler to invoke for the current element. /// </summary> /// <param name="element">The element for which event handlers are being invoked.</param> /// <param name="evt">A <see cref="RoutedEvent"/> which identifies the routed event for which handlers are being invoked.</param> /// <param name="index">The index of the handler to invoke; this value is incremented by one when this method returns.</param> /// <param name="handler">The metadata for the handler that corresponds to the specified index within the handler list.</param> /// <returns><see langword="true"/> if a handler was retrieved for the specified index; otherwise, <see langword="false"/>.</returns> private static Boolean GetEventHandler(DependencyObject element, RoutedEvent evt, ref Int32 index, ref RoutedEventHandlerMetadata handler) { var indexTemp = index; var classHandlers = RoutedEventClassHandlers.GetClassHandlers(element.GetType(), evt); if (classHandlers != null) { lock (classHandlers) { if (indexTemp >= 0 && indexTemp < classHandlers.Count) { handler = classHandlers[indexTemp]; index++; return(true); } indexTemp -= classHandlers.Count; } } var uiElement = element as UIElement; if (uiElement != null) { var instanceHandlers = uiElement.GetHandlers(evt); if (instanceHandlers == null) { return(false); } lock (instanceHandlers) { if (indexTemp >= instanceHandlers.Count) { return(false); } handler = instanceHandlers[indexTemp]; index++; } return(true); } else { return(false); } }