5

I'm trying to register handler for all Loaded events:

EventManager.RegisterClassHandler(typeof(UIElement), FrameworkElement.LoadedEvent, new RoutedEventHandler(OnRoutedEvent), true);
EventManager.RegisterClassHandler(typeof(ContentElement), FrameworkContentElement.LoadedEvent, new RoutedEventHandler(OnRoutedEvent), true);
EventManager.RegisterClassHandler(typeof(UIElement), FrameworkElement.UnloadedEvent, new RoutedEventHandler(OnRoutedEvent), true);
EventManager.RegisterClassHandler(typeof(ContentElement), FrameworkContentElement.UnloadedEvent, new RoutedEventHandler(OnRoutedEvent), true);

Unfortunately my handler is only called for Window and descendants of DatePicker. It does not work for any other type.

Can anyone explain this behavior ? It's a bug, sadly they've chosen to ignore it.

Is there some other way to be notified about any new element in application/window ?

Marcin Wisnicki
  • 4,511
  • 4
  • 35
  • 57
  • Whereabouts have you put the RegisterClassHandlers? In App.cs? – Colin Smith Jul 12 '12 at 20:02
  • Yup, in static constructor but it doesn't matter since class handlers are broken anyway (see the bug above) ;( – Marcin Wisnicki Jul 13 '12 at 08:57
  • This is a long shot and a bit hacky, but could you instead do a RegisterClassHandler for FrameworkElement.Initialized events (i.e. created but not rendered yet)...then in that callback call AddHandler on the UIElement instance to wire up the Loaded and Unloaded events. – Colin Smith Jul 13 '12 at 10:27
  • 1
    FrameworkElement.Initialized is not a RoutedEvent so this is not possible. For now the best event I've found is FE.SizeChangedEvent combined with WeakHashMap to skip objects already seen. Unfortunately there is no equivalent event in FCE. – Marcin Wisnicki Jul 13 '12 at 10:41
  • 1
    Perhaps you could define an AttachedProperty/Behavior that uses FrameworkPropertyMetadataOptions.Inherits, and then specify it on your root element, and in the behaviour hook the Loaded/Unloaded events on each instance. – Colin Smith Jul 13 '12 at 11:52
  • Excellent! I was sure it only fires for elements with explicit assignment but it seems to travel down the whole tree. Please respond with proper answer so I can mark it as such. – Marcin Wisnicki Jul 13 '12 at 12:54

1 Answers1

6

Perhaps you could define an AttachedProperty/Behavior<T> that uses FrameworkPropertyMetadataOptions.Inherits, and then specify it on your root element, and in the behaviour hook the Loaded/Unloaded events on each instance

Colin Smith
  • 12,375
  • 4
  • 39
  • 47
  • 1
    Additionally to hook new windows one can abuse SizeChangedEvent to invoke custom initializer. My code is here: https://gist.github.com/3104963 – Marcin Wisnicki Jul 13 '12 at 13:47