VisualTreeHelper Clase
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Proporciona métodos de utilidad que se pueden usar para atravesar las relaciones de objetos (a lo largo del objeto secundario o ejes primarios) en el árbol visual de la aplicación.
public ref class VisualTreeHelper sealed
/// [Windows.Foundation.Metadata.ContractVersion(Microsoft.UI.Xaml.WinUIContract, 65536)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class VisualTreeHelper final
[Windows.Foundation.Metadata.ContractVersion(typeof(Microsoft.UI.Xaml.WinUIContract), 65536)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public sealed class VisualTreeHelper
Public NotInheritable Class VisualTreeHelper
- Herencia
- Atributos
Ejemplos
Este es un ejemplo de una función de utilidad que puede copiar una lista de elementos secundarios de un tipo determinado desde dentro de un árbol visual. Usa los métodos transversales básicos GetChildrenCount y GetChild. Usa recursividad para que se puedan encontrar elementos independientemente del nivel de anidamiento en contenedores intermedios. También usa un método de extensión IsSubclassOf de System.Reflection que extiende la comparación de tipos para considerar los subtipos como una coincidencia para un tipo.
internal static void FindChildren<T>(List<T> results, DependencyObject startNode)
where T : DependencyObject
{
int count = VisualTreeHelper.GetChildrenCount(startNode);
for (int i = 0; i < count; i++)
{
DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
{
T asType = (T)current;
results.Add(asType);
}
FindChildren<T>(results, current);
}
}
Comentarios
Árbol visual
El propósito de la clase VisualTreeHelper es ayudar con la detección de objetos que está buscando en el árbol en tiempo de ejecución de objetos, pero no hay una API de relación de objetos más directa disponible para su escenario. A veces, no sabrá el tipo exacto ni el nombre del objeto. O quizás sepa que un objeto específico aparece en algún lugar del árbol, pero no conoce la posición exacta. Para estos tipos de escenarios, VisualTreeHelper es útil porque puede encontrar recursivamente todos los objetos en el árbol visual y, a continuación, examinar este conjunto y buscar una coincidencia en función de los criterios.
El árbol visual de una aplicación se puede conceptualizar como una representación filtrada del árbol de objetos más grande de los objetos y propiedades de una aplicación. Solo los objetos que tienen una implicación de representación están presentes en un árbol visual. Por ejemplo, una clase de colección no formaría parte del árbol visual. En su lugar, el árbol visual abstrae cualquier colección en un concepto de "elementos secundarios".
Sin embargo, el árbol visual también puede incluir objetos que no están representados como elementos XAML en el marcado XAML de una página. Esto se debe a que el árbol visual agrega objetos que son las partes compuestas de controles. Estas partes de control pueden provenir de una plantilla de control aplicada, que normalmente es XAML de un elemento de diccionario de recursos o de un moderador.
El marcado XAML y un árbol visual no coinciden exactamente con el nodo para nodo porque XAML está diseñado para marcado y facilidad de uso durante la definición de marcado, por lo que a veces tiene elementos adicionales. Por ejemplo, XAML tiene elementos de propiedad, que establece los valores de propiedad si se encuentra un elemento anidado dentro de otro. En un árbol visual, esto solo tendría un aspecto similar a una propiedad de un objeto que otro objeto establece. XAML también tiene un concepto de una propiedad de contenido, donde la propiedad que se establece no se designa explícitamente en el marcado. Para obtener más información sobre la terminología específica y las reglas de XAML, consulta Introducción a XAML.
El árbol visual se usa internamente para el proceso de representación de la interfaz de usuario, pero conocer la estructura del árbol visual es importante para determinados escenarios, como escribir o reemplazar una plantilla de control, o el análisis de la estructura y los elementos de un control en tiempo de ejecución. En estos escenarios, el Windows Runtime proporciona la API de VisualTreeHelper que puede examinar el árbol visual de una manera más generalizada. (En teoría, podría construir este árbol mediante propiedades primarias y secundarias específicas del objeto, pero tendría que saber exactamente qué propiedades admite cada elemento y eso es difícil de detectar o administrar).
Normalmente, combina varias llamadas API de VisualTreeHelper para escribir sus propias funciones auxiliares que investigan el árbol visual de maneras específicas de los escenarios de su propia aplicación.
Recorrido de un árbol visual
Recorrer el árbol de objetos (a veces conocidos coloquialmente como caminar por el árbol) es una técnica común en los modelos de objetos. Se usan propiedades que hacen referencia a objetos secundarios (normalmente son colecciones) o relaciones primarias a un objeto contenedor (normalmente esto se hace desde dentro de una colección y devuelve la propia colección). Como descripción aproximada del proceso, se llama a una sucesión de propiedades secundarias y propiedades primarias, o quizás métodos auxiliares, para navegar por los ejes del árbol de objetos hasta recuperar un valor que contiene el objeto que estaba buscando. Como regla general, debes poder construir el contenido en XAML de forma que no necesites consultar la estructura del árbol de forma exhaustiva. Para evitar la necesidad de recorrer el árbol, debes proporcionar a los elementos XAML un valor para el atributo x:Name / Name en el marcado XAML que los crea. Esto crea una referencia inmediata que está disponible para el acceso al código en tiempo de ejecución y es una técnica mucho menos propensa a errores para obtener referencias de objetos que caminar por el árbol. Como alternativa, si vas a crear objetos a través de código en lugar de XAML, debes declarar campos o variables privados que conserven la referencia de objeto en tiempo de ejecución. Normalmente, no es necesario recorrer el árbol para buscar objetos creados en su propio código.
Sin embargo, hay casos en los que no es posible o práctico asignar un nombre a un objeto y mantener una referencia de objeto en el ámbito. Un escenario de este tipo es si va a agregar contenido dinámico proporcionado por el usuario o proporcionado por el enlace de datos, o mediante modelos de vista y objetos empresariales. En estos casos, no siempre puede predecir el número de elementos agregados o la estructura de un control y sus elementos secundarios. Otro escenario es examinar una plantilla aplicada para un control o una sección compuesta de un contenido de control o moderador.
El recorrido del árbol hacia abajo (lejos de la raíz) se puede realizar mediante GetChildrenCount para valores distintos de cero y, a continuación, GetChild para solicitar un índice específico. Es posible que tenga que usar técnicas try/catch o el equivalente si intenta convertir elementos como subtipos UIElement específicos. Por lo general, la API VisualTreeHelper devuelve elementos como dependencyObject y tendrá que convertirlo para poder hacer cualquier cosa útil (incluso para una operación tan simple como comprobar su valor name ).
Métodos
| Nombre | Description |
|---|---|
| DisconnectChildrenRecursive(UIElement) |
Quita explícitamente todas las referencias de un UIElement de destino, con el objetivo de limpiar los ciclos de referencia. |
| FindElementsInHostCoordinates(Point, UIElement, Boolean) |
Recupera un conjunto de objetos que se encuentran dentro de un punto de coordenada x-y especificado de una interfaz de usuario de la aplicación. El conjunto de objetos representa los componentes de un árbol visual que comparten ese punto. |
| FindElementsInHostCoordinates(Point, UIElement) |
Recupera un conjunto de objetos que se encuentran dentro de un punto de coordenada x-y especificado de una interfaz de usuario de la aplicación. El conjunto de objetos representa los componentes de un árbol visual que comparten ese punto. |
| FindElementsInHostCoordinates(Rect, UIElement, Boolean) |
Recupera un conjunto de objetos que se encuentran dentro de un marco rect especificado de una interfaz de usuario de la aplicación. El conjunto de objetos representa los componentes de un árbol visual que comparten un área rectangular y puede incluir elementos que se superponen. |
| FindElementsInHostCoordinates(Rect, UIElement) |
Recupera un conjunto de objetos que se encuentran dentro de un marco rect especificado de una interfaz de usuario de la aplicación. El conjunto de objetos representa los componentes de un árbol visual que comparten un área rectangular y puede incluir elementos que se superponen. |
| GetChild(DependencyObject, Int32) |
Con el índice proporcionado, obtiene un objeto secundario específico del objeto proporcionado examinando el árbol visual. |
| GetChildrenCount(DependencyObject) |
Devuelve el número de elementos secundarios que existen en la colección secundaria de un objeto en el árbol visual. |
| GetOpenPopups(Window) |
Recupera una colección de todos los controles emergentes abiertos de la ventana de destino. |
| GetOpenPopupsForXamlRoot(XamlRoot) |
Recupera una colección de todos los controles emergentes abiertos del xamlRoot de destino. |
| GetParent(DependencyObject) |
Devuelve el objeto primario de un objeto en el árbol visual. |