VisualTreeHelper Clase

Definición

Proporciona métodos de utilidad que se pueden usar para atravesar relaciones de objeto (a lo largo de ejes de objetos secundarios o primarios) en el árbol visual de la aplicación.

public ref class VisualTreeHelper sealed
/// [Windows.Foundation.Metadata.ContractVersion(Windows.Foundation.UniversalApiContract, 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(Windows.Foundation.UniversalApiContract), 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
Object Platform::Object IInspectable VisualTreeHelper
Atributos

Requisitos de Windows

Familia de dispositivos
Windows 10 (se introdujo en la versión 10.0.10240.0)
API contract
Windows.Foundation.UniversalApiContract (se introdujo en la versión v1.0)

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 de recorrido básicos GetChildrenCount y GetChild. Usa recursividad para que los elementos se puedan encontrar independientemente del nivel de anidamiento dentro de los 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 conocerá el tipo exacto ni el nombre del objeto. O quizá 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 buscar de forma recursiva todos los objetos del árbol visual y, a continuación, buscar una coincidencia según sus 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 se representan 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 los controles. Estas partes de control pueden proceder de una plantilla de control aplicada, que suele ser 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 valores de propiedad si se encuentra un elemento anidado dentro de otro. En un árbol visual, esto tendría un aspecto similar a una propiedad en 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 Información general sobre 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 VisualTreeHelper que puede examinar el árbol visual de una manera más generalizada. (En teoría, podría construir este árbol con 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 sus propios escenarios de la aplicación.

Recorrido de un árbol visual

Recorrer el árbol de objetos (a veces conocido 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 ampliamente. Para evitar la necesidad de recorrer el árbol, debes proporcionar a los elementos XAML un valor para el atributo x: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 mediante código en lugar de XAML, debes declarar campos privados o variables 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. Uno de estos escenarios 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.

Recorrer el árbol hacia abajo (lejos de la raíz) se puede realizar varios niveles 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 de VisualTreeHelper devuelve elementos como dependencyObject y tendrá que convertirlo para hacer cualquier cosa útil (incluso para una operación tan simple como comprobar su valor name ).

Notas de las versiones anteriores

Windows 8

Subprocesamiento de la interfaz de usuario

Windows 8 llamadas de función de VisualTreeHelper permitidas que hacían referencia a objetos en el subproceso de interfaz de usuario incorrecto (no en el actual). A partir de Windows 8.1, la función produce una excepción si no se llama desde el subproceso de interfaz de usuario actual. Tener en cuenta este nuevo comportamiento debe ser un escenario de migración de aplicaciones muy poco común; es difícil obtener elementos de interfaz de usuario entre subprocesos en primer lugar.

Las aplicaciones compiladas para Windows 8 pero que se ejecutan en Windows 8.1 usan el comportamiento de Windows 8.1 y se producirán específicamente en la llamada de función VisualTreeHelper en lugar de en cualquier código de aplicación de bajada que use un objeto entre subprocesos.

Interfaz de usuario de la aplicación para el teclado en pantalla

Windows 8 tenía una lógica implementada internamente que asociaría un ScrollViewer con la interfaz de usuario general de la aplicación cada vez que el usuario invoca el teclado en pantalla. Este teclado en pantalla es una característica de accesibilidad específica que los usuarios solicitan a través del Centro de acceso fácil. No es lo mismo que el teclado suave que puede aparecer en la interfaz de usuario de la aplicación para los controles de entrada de texto, si el sistema no detecta ningún dispositivo de teclado. Lo que hace scrollViewer interno aquí es que sea posible desplazarse por el área donde está la aplicación, si se desplaza, porque el teclado está tomando espacio en la interfaz de usuario.

A partir de Windows 8.1, el sistema sigue teniendo un comportamiento de diseño o interfaz de usuario cuando aparece el teclado en pantalla, pero ya no usa este ScrollViewer creado internamente. En su lugar, usa un control interno dedicado que el código de la aplicación no puede cambiar ni inspeccionar.

La mayoría de los aspectos de este cambio de comportamiento no afectan a las aplicaciones en absoluto. Sin embargo, es posible que la aplicación haya previsto este comportamiento, proporcionando un estilo implícito para ScrollViewer destinado a cambiar el diseño, o caminando por el árbol con VisualTreeHelper para encontrar este ScrollViewer creado internamente y modificarlo en tiempo de ejecución. Para una aplicación compilada para Windows 8.1 ese código no será útil.

Las aplicaciones compiladas para Windows 8 que se ejecuten en Windows 8.1 siguen usando el comportamiento de Windows 8.

Historial de versiones

Versión de Windows Versión del SDK Valor agregado
1903 18362 GetOpenPopupsForXamlRoot

Métodos

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)

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, 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(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 podría incluir elementos que se superponen.

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 podría 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 de XamlRoot de destino.

GetParent(DependencyObject)

Devuelve el objeto primario de un objeto en el árbol visual.

Se aplica a

Consulte también