VisualTreeHelper Classe

Definição

Fornece métodos utilitários que podem ser usados para percorrer relações de objeto (ao longo de eixos filho-objeto ou pai-objeto) na árvore visual do seu aplicativo.

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
Herança
Object Platform::Object IInspectable VisualTreeHelper
Atributos

Requisitos do Windows

Família de dispositivos
Windows 10 (introduzida na 10.0.10240.0)
API contract
Windows.Foundation.UniversalApiContract (introduzida na v1.0)

Exemplos

Aqui está um exemplo de uma função de utilitário que pode copiar uma lista de elementos filho de um tipo específico de dentro de uma árvore visual. Ele usa os métodos básicos de passagem GetChildrenCount e GetChild. Ele usa recursão para que os elementos possam ser encontrados independentemente do nível de aninhamento dentro de contêineres intermediários. Ele também usa um método de extensão IsSubclassOf de System.Reflection que estende a comparação de tipos para considerar subtipos como uma correspondência para um 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);
    }
}

Comentários

A árvore visual

A finalidade da classe VisualTreeHelper é ajudar na descoberta de objetos que você está procurando na árvore de runtime de objetos, mas não há uma API de relação de objeto mais direta disponível para seu cenário. Às vezes, você não saberá o tipo exato ou o nome do objeto. Ou talvez você saiba que um objeto específico aparece em algum lugar na árvore, mas você não sabe a posição exata. Para esses tipos de cenários, o VisualTreeHelper é útil porque você pode localizar recursivamente todos os objetos na árvore visual e, em seguida, examinar esse conjunto e procurar uma correspondência com base em seus critérios.

A árvore visual de um aplicativo pode ser conceituada como uma representação filtrada da árvore de objetos maior dos objetos e propriedades de um aplicativo. Somente os objetos que têm uma implicação de renderização estão presentes em uma árvore visual. Por exemplo, uma classe de coleção não faria parte da árvore visual. Em vez disso, a árvore visual abstrai qualquer coleção em um conceito "children".

No entanto, a árvore visual também pode incluir objetos que não são representados como elementos XAML na marcação XAML de uma página. Isso ocorre porque a árvore visual adiciona objetos que são as partes compostas de controles. Essas partes de controle podem vir de um modelo de controle aplicado, que geralmente é XAML de um item de dicionário de recursos ou de um apresentador.

A marcação XAML e uma árvore visual não correspondem exatamente ao nó para nó porque o XAML foi projetado para marcação e facilidade de uso durante a definição de marcação, portanto, às vezes tem elementos extras. Por exemplo, XAML tem elementos de propriedade, que define valores de propriedade se um elemento for encontrado aninhado dentro de outro. Em uma árvore visual, isso se pareceria apenas com uma propriedade em um objeto que está sendo definido por outro objeto. O XAML também tem um conceito de uma propriedade de conteúdo, em que a propriedade que está sendo definida não é explicitamente designada na marcação. Para obter mais informações sobre a terminologia específica e as regras para XAML, consulte Visão geral do XAML.

A árvore visual é usada internamente para o processo de renderização da interface do usuário, mas conhecer a estrutura da árvore visual é importante para determinados cenários, como gravar ou substituir um modelo de controle ou a análise da estrutura e das partes de um controle em tempo de execução. Para esses cenários, o Windows Runtime fornece a API VisualTreeHelper que pode examinar a árvore visual de uma maneira mais generalizada. (Teoricamente, você poderia construir essa árvore usando propriedades pai e filhos específicas do objeto também, mas teria que saber exatamente quais propriedades cada elemento tinha suporte e isso é difícil de descobrir ou gerenciar.)

Normalmente, você combina várias chamadas à API do VisualTreeHelper para escrever suas próprias funções auxiliares que investigam a árvore visual de maneiras específicas para os cenários do seu próprio aplicativo.

Atravessando uma árvore visual

Atravessar a árvore de objetos (às vezes conhecida coloquialmente como andar na árvore) é uma técnica comum em modelos de objeto. Você usa propriedades que fazem referência a objetos filho (normalmente são coleções) ou relações pai a um objeto que contém (geralmente isso é feito de dentro de uma coleção e retorna a coleção em si). Como uma descrição aproximada do processo, você chama uma sucessão de propriedades filho e propriedades pai, ou talvez métodos auxiliares, para navegar pelos eixos da árvore de objetos até recuperar um valor que contém o objeto que você estava procurando. Como regra geral, você deve ser capaz de construir seu conteúdo em XAML de modo que você não precise consultar extensivamente a estrutura da árvore. Para evitar a necessidade de percorrer a árvore, você deve dar aos elementos XAML um valor para o atributo x:Name / Name na marcação XAML que os cria. Isso cria uma referência imediata que está disponível para acesso ao código em tempo de execução e essa é uma técnica muito menos propensa a erros para obter referências de objeto do que andar na árvore. Como alternativa, se você estiver criando objetos por meio de código em vez de XAML, deverá declarar campos privados ou variáveis que retêm a referência de objeto em tempo de execução. Normalmente, não é necessário atravessar a árvore para encontrar objetos criados em seu próprio código.

No entanto, há casos em que não é possível ou prático dar um nome a um objeto e manter uma referência de objeto no escopo. Um desses cenários é se você estiver adicionando conteúdo dinâmico fornecido pelo usuário ou fornecido pela associação de dados ou usando modelos de exibição e objetos de negócios. Nesses casos, você nem sempre pode prever o número de itens adicionados ou a estrutura de um controle e seus filhos. Outro cenário é examinar um modelo aplicado para um controle ou uma seção composta de um controle ou conteúdo do apresentador.

A passagem da árvore para baixo (longe da raiz) de vários níveis pode ser feita usando GetChildrenCount para valores não zero e, em seguida, GetChild para solicitar um índice específico. Talvez seja necessário usar técnicas try /catch ou o equivalente se estiver tentando converter elementos como subtipos UIElement específicos. Geralmente, a API visualTreeHelper retorna elementos como um DependencyObject e você precisará convertê-lo para fazer qualquer coisa útil (mesmo para uma operação tão simples quanto verificar seu valor de Nome ).

Anotações para versões anteriores

Windows 8

Threading de interface do usuário

Windows 8 chamadas de função do VisualTreeHelper permitidas que estavam referenciando objetos no thread de interface do usuário errado (não no atual). Começando com Windows 8.1, a função gerará uma exceção se não estiver sendo chamada do thread de interface do usuário atual. A contabilidade desse novo comportamento deve ser um cenário de migração de aplicativo muito incomum; É difícil obter elementos de interface do usuário entre threads em primeiro lugar.

Os aplicativos que foram compilados para Windows 8 mas executados no Windows 8.1 usam o comportamento Windows 8.1 e serão lançados especificamente na chamada de função VisualTreeHelper em vez de em qualquer código de aplicativo downstream que use um objeto entre threads.

Interface do usuário do aplicativo para teclado virtual

Windows 8 tinha uma lógica implementada internamente que associaria um ScrollViewer à interface do usuário geral do aplicativo sempre que o usuário invocasse o Teclado Virtual. Esse Teclado Virtual é um recurso de acessibilidade específico que os usuários solicitam por meio da Central de Facilidade de Acesso. Não é o mesmo que o teclado flexível que pode aparecer na interface do usuário do aplicativo para controles de entrada de texto, se o sistema não detectar nenhum dispositivo de teclado. O que o ScrollViewer interno faz aqui é possibilitar rolar a área onde o aplicativo está, se a rolagem for forçada porque o teclado está tomando espaço na interface do usuário.

Começando com Windows 8.1, o sistema ainda tem comportamento de interface do usuário/layout quando o Teclado Virtual é exibido, mas não usa mais esse ScrollViewer criado internamente. Em vez disso, ele usa um controle interno dedicado que o código do aplicativo não pode alterar ou inspecionar.

A maioria dos aspectos dessa alteração de comportamento não afeta os aplicativos. No entanto, seu aplicativo pode ter antecipado esse comportamento, fornecendo um Estilo implícito para ScrollViewer destinado a alterar o layout ou andando na árvore com o VisualTreeHelper para encontrar esse ScrollViewer criado internamente e alterá-lo em tempo de execução. Para um aplicativo compilado para Windows 8.1 esse código não será útil.

Os aplicativos que foram compilados para Windows 8, mas estão sendo executados no Windows 8.1, continuam a adotar o comportamento do Windows 8.

Histórico de versão

Versão do Windows Versão do SDK Valor adicionado
1903 18362 GetOpenPopupsForXamlRoot

Métodos

DisconnectChildrenRecursive(UIElement)

Remove explicitamente todas as referências de um UIElement de destino, com o objetivo de limpar ciclos de referência.

FindElementsInHostCoordinates(Point, UIElement, Boolean)

Recupera um conjunto de objetos localizados em um ponto de coordenada x-y especificado de uma interface do usuário do aplicativo. O conjunto de objetos representa os componentes de uma árvore visual que compartilham esse ponto.

FindElementsInHostCoordinates(Point, UIElement)

Recupera um conjunto de objetos localizados em um ponto de coordenada x-y especificado de uma interface do usuário do aplicativo. O conjunto de objetos representa os componentes de uma árvore visual que compartilham esse ponto.

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

Recupera um conjunto de objetos que estão localizados em um quadro rect especificado de uma interface do usuário do aplicativo. O conjunto de objetos representa os componentes de uma árvore visual que compartilham uma área retangular e pode incluir elementos que se sobressaem.

FindElementsInHostCoordinates(Rect, UIElement)

Recupera um conjunto de objetos que estão localizados em um quadro rect especificado de uma interface do usuário do aplicativo. O conjunto de objetos representa os componentes de uma árvore visual que compartilham uma área retangular e pode incluir elementos que se sobressaem.

GetChild(DependencyObject, Int32)

Usando o índice fornecido, obtém um objeto filho específico do objeto fornecido examinando a árvore visual.

GetChildrenCount(DependencyObject)

Retorna o número de filhos que existem na coleção filho de um objeto na árvore visual.

GetOpenPopups(Window)

Recupera uma coleção de todos os controles pop-up abertos da Janela de destino.

GetOpenPopupsForXamlRoot(XamlRoot)

Recupera uma coleção de todos os controles pop-up abertos do XamlRoot de destino.

GetParent(DependencyObject)

Retorna o objeto pai de um objeto na árvore visual.

Aplica-se a

Confira também