/// <summary> /// Removes the <see cref="FrameworkElement"/> with the given <see cref="EventDefinition"/> from Tracking. /// </summary> /// <param name="element"></param> /// <param name="event"></param> private void RemoveEventHandler(FrameworkElement element, EventDefinition @event) { IEnumerable <KeyValuePair <FrameworkElementEvent, Delegate> > registerd = null; if (@event.AssignRecursively || [email protected](element)) { registerd = EventDelegates.Where(i => i.Key.Event.Equals(@event)).ToList(); } else { var key = new FrameworkElementEvent(element, @event, Element); registerd = EventDelegates.Where(i => i.Key.Equals(key)).ToList(); } if (registerd.Count() > 0) { foreach (var item in registerd) { var info = @event.GetEventInfo(item.Key.Element.GetType()); info.RemoveEventHandler(item.Key.Element, item.Value); EventDelegates.Remove(item.Key); Config.Instance.WriteLog(this, $"Removed {item.Key?.Element?.ToString()} with EventType {item.Key?.Event?.EventType.ToString()} to Tracked Events of {Element?.ToString()}.", Enums.LogType.Info); } } }
/// <summary> /// Adds the EventDelegate to the event handler for the given Event. If the EventType is not Assignable to the given FrameworkElement, /// it will Query through the Visual Tree and register this Event to the first FrameworkElement in each path where it fits. /// Method is not running Synchronous, it will add the event handlers in the Loaded Event, when the given Framework Element is not actually part of the Visual tree. /// </summary> /// <param name="element"></param> /// <param name="event"></param> /// <param name="trackingElement"></param> private void AddEventHandler(FrameworkElement element, EventDefinition @event, FrameworkElement trackingElement) { var key = new FrameworkElementEvent(element, @event, trackingElement); //Check if Event is already Added if (!EventDelegates.ContainsKey(key)) { Action <object, EventArgs> loadedAction = (sender, e) => { var children = element.GetChildren().Where(i => i is FrameworkElement).Cast <FrameworkElement>().ToList(); foreach (var child in children) { AddEventHandler(child, @event, trackingElement); } }; //Test if Event is assignable if (@event.IsAssignable(element)) { //Register Delegate var @delegate = Delegate.CreateDelegate( @event.Description.EventHandler, key, key.GetType() .GetMethod("EventDelegate", BindingFlags.NonPublic | BindingFlags.Instance)); RegisterDelegate(element, @delegate, @event); EventDelegates.Add(key, @delegate); Config.Instance.WriteLog(this, $"Adding {key?.Element?.ToString()} with EventType {key?.Event?.EventType.ToString()} to Tracked Events of {Element?.ToString()}.", Enums.LogType.Info); if (@event.AssignRecursively) { var parent = VisualTreeHelper.GetParent(element); var cCount = VisualTreeHelper.GetChildrenCount(element); if (parent == null && cCount == default(int)) { //Creating a delegate with Executes this after Loaded Event, because then is the Visual tree generated. element.Loaded += (sender, e) => loadedAction(sender, e); } else { //Element is attached to Visual Tree so get the Children directly loadedAction.Invoke(element, new RoutedEventArgs()); } } } else { //If not assignable: Query the visual tree for Elements where the Event can be Assigned to var parent = VisualTreeHelper.GetParent(element); var cCount = VisualTreeHelper.GetChildrenCount(element); if (parent == null && cCount == default(int)) { //Creating a delegate with Executes this after Loaded Event, because then is the Visual tree generated. element.Loaded += (sender, e) => loadedAction(sender, e); } else { //Element is attached to Visual Tree so get the Children directly loadedAction.Invoke(element, new RoutedEventArgs()); } } } }