Buscar el control primario de un tipo específico en WPF y Silverlight
Sé que esto no es un truco secreto innovador y alucinante, pero he recibido una cantidad sorprendente de preguntas sobre cómo encontrar el padre de un tipo específico para un control.
La capacidad de encontrar un control primario basado en un tipo resulta muy útil cuando se componen vistas dinámicamente, como en una aplicación Prism. Hay muchos otros escenarios en los que esto es útil, pero la solicitud más reciente se basó en mi publicación sobre el adaptador de región de prisma de XamDockManager. Alguien quería crear un comportamiento que se adjuntara a su vista, que se inserta en un ContentPane, para controlar si el ContentPane se podía cerrar o no. Pues bien, dado que el evento Closing cancelable existe en el propio control ContentPane y no en la View que se estaba insertando, necesitaban acceso al elemento primario de tipo ContentPane desde el comportamiento. Bueno, por suerte para ellos, esto es realmente fácil de hacer.
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
else
return FindParent<T>(parentObject);
}
Este sencillo fragmento de código recorrerá el árbol visual del control en busca de un control primario que coincida con el tipo específico proporcionado. Para usarlo, simplemente llame al método FindParent<T>, donde T es el tipo que está buscando y, a continuación, pase el control en el que desee al elemento primario de.
ContentPane _parentContentPane = FindParent<ContentPane>(this);
if (_parentContentPane != null)
_parentContentPane.Closing += _parentContentPane_Closing;
En este ejemplo concreto se busca en el árbol visual de un control de usuario el ContentPane de xamDockManager que contiene la instancia de control de usuario. Ah, ¿y mencioné que este fragmento de código exacto funcionará igual tanto en WPF como en Silverlight? ¡Eso fue fácil!
No dudes en ponerte en contacto conmigo en mi blog, conéctate conmigo en Twitter (@brianlagunas) o deja un comentario a continuación para cualquier pregunta o comentario que puedas tener.