内置的WPF控件如何管理他们的事件处理程序到一个附加事件? [英] How built-in WPF controls manage their event handlers to an attached event?

查看:113
本文介绍了内置的WPF控件如何管理他们的事件处理程序到一个附加事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道当你注册一个对象到鼠标的附件事件时,你有内存泄漏。这就是为什么您需要使用 WeakEvent模式的原因。



我有这个模式的问题:如果你想使用它,你不能在XAML代码中定义你的处理程序。



To我,这意味着每一个这样的代码泄漏:

 < SomeControl Mouse.MouseDown =MyHandler/> 

除非你在代码中明确删除你的处理程序(我怀疑有人这样做)。
现在有一些我不明白的东西:

 < Button Click =MyHandler/> 

此代码以某种方式使用Mouse.MouseDown事件来检测按钮上的点击。
通过反射器的一些研究,我发现这个事件使用UIElement类的MouseDown。当我阅读UIElement的代码我不明白:没有WeakEventManager!



有人可以解释一下UIElement如何从Mouse.MouseDown接收事件而不泄漏?

解决方案

使用XAML中的普通处理程序不需要弱引用。



您正在做的是在主控件和该控件中包含的子控件之间创建内存引用;在这种情况下,子控件是按钮。



如果有人维护对主控件的视觉树的任何部分的引用,则整个树将保留在内存中,因为它被链接在一起(父/子引用)。



现在,如果对这个树的所有引用都被删除,父和子之间的事件引用(主控件和该按钮)不重要,因为这些控件已经通过父/子引用进行链接。一旦外部引用被删除,这个控件就可以被垃圾回收。



XAML中的事件处理程序只能创建内部事件引用。



外部客户端注册时必须小心一个控件上的事件,因为您正在创建一个外部引用,只要链接和客户端存在(即使是弱引用),它将保持控制活动。



<你的问题是关于附加的事件。关于附加事件是否导致内存泄漏似乎没有任何明确的文档。它看起来像我的UI控件,订阅事件包含对事件的引用而不是其他方式,但我认为静态事件对象必须有一些方式通知控件已被触发。微软似乎对此缺乏评论。


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 ?

解决方案

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.

这篇关于内置的WPF控件如何管理他们的事件处理程序到一个附加事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆