2009-02-09 7 views
5

Sé que cuando registra un objeto para los eventos adjuntos del mouse, tiene fugas de memoria. Es por eso que necesita usar WeakEvent pattern.¿Cómo los controles WPF incorporados administran sus manejadores de eventos a un evento adjunto?

Tengo un problema con este patrón: si quieres usarlo, no puedes definir tu controlador en el código XAML.

Para mí, significa que cada código como este se escapa:

<SomeControl Mouse.MouseDown="MyHandler" /> 

menos que se quite el controlador de forma explícita en el código (y dudo que cualquiera hace eso). Ahora hay algo que no entiendo:

<Button Click="MyHandler" /> 

Este código utiliza alguna manera en algún lugar del evento Mouse.MouseDown para detectar un clic en el botón. Investigué un poco con un reflector y descubrí que este evento usa MouseDown de la clase UIElement. Y cuando leo el código de UIElement no entiendo: ¡no hay un WeakEventManager!

¿Alguien puede explicarme cómo UIElement recibe eventos de Mouse.MouseDown sin fugas?

Respuesta

7

El uso de controladores normales en XAML no requiere referencias débiles.

Lo que está haciendo es crear una referencia de memoria entre el control principal y un control secundario contenido dentro de este control; el control infantil en este caso es el botón.

Si alguien mantiene una referencia a cualquier parte del árbol visual para el control principal, todo el árbol permanecerá en la memoria porque está vinculado entre sí (referencias padre/hijo).

Ahora, si se eliminan todas las referencias a este árbol, la referencia de evento entre padre e hijo (el control principal y el botón) no es significativa porque estos controles ya estaban vinculados mediante referencias padre/hijo. Una vez que se eliminan todas las referencias externas, este control se puede recolectar como basura.

Los controladores de eventos dentro de XAML solo crean referencias de eventos internos.

Debe tener cuidado cuando los clientes externos se registran en un evento en un control, porque está creando una referencia externa que mantendrá el control activo mientras exista el enlace y el cliente (a menos que sea una referencia débil) .

Su pregunta es acerca de eventos adjuntos. No parece haber ninguna documentación clara sobre si los eventos adjuntos causan pérdidas de memoria. Me parece que el control de UI que se suscribe al evento contiene referencias al evento en lugar de al revés, pero asumo que el objeto de evento estático debe tener alguna forma de notificar al control que se ha disparado. Parece que hay una sorprendente falta de comentarios sobre esto por parte de Microsoft.

+0

Estoy de acuerdo con usted, sin embargo, el controlador en XAML a un evento adjunto (no hablo de eventos de controles, sino eventos como Mouse.MouseDown) puede tener fugas, porque siempre hay una referencia en él. Internamente, la clase de botón usa Mouse.MouseDown events (UIElement para ser específico) .Y no sé por qué esto no tiene fugas. –

+0

Buen punto. Los eventos adjuntos son referencias externas. –

Cuestiones relacionadas