How built-in WPF controls manage their event handl

2020-04-07 12:25发布

问题:

I know that when you register an object to the mouse's attached events, you have memory leaks. That's why you need to use WeakEvent pattern.

I have a problem with this pattern : If you want to use it, you cannot define your handler in the XAML code.

To me, it means that every code like this leaks :

<SomeControl Mouse.MouseDown="MyHandler" />

Unless you remove your handler explicitly in code (And I doubt that anybody does that). Now there is something I don't understand :

<Button Click="MyHandler" />

This code somehow use somewhere the Mouse.MouseDown event to detect a click on the button. With some research with reflector, I found that this event use MouseDown of the UIElement class. And when I read the code of UIElement I don't understand : there is no WeakEventManager !

Can someone can explain me how UIElement recieve events from Mouse.MouseDown without leak ?

回答1:

Using normal handlers in XAML does not require weak references.

What you are doing is creating a memory reference between the main control and a child control contained within this control; the child control in this case is the button.

If someone maintains a reference to any part of the visual tree for the main control, the whole tree will stay in memory because it is linked together (parent/child references).

Now if all of the references to this tree are removed, the event reference between parent and child (the main control and the button) is not significant because these controls were already linked through parent/child references. Once all external references are removed, this control can be garbage collected.

Event handlers within XAML only create internal event references.

You have to be careful when external clients register to an event on a control, because you are creating an external reference that will keep the control alive as long as the link and the client exists (unless it is a weak reference).

Your question is about attached events. There doesn't appear to be any clear documentation on whether attached events cause memory leaks. It looks to me like the UI control that subscribes to the event contains a references to the event instead of the other way around, but I assume that the static event object must have some way of notifying the control that it has been fired. There appears to be a surprising lack of comment on this from Microsoft.