Partilhar via


Árvores em WPF

Muitas tecnologias, elementos e componentes são organizados em uma estrutura de árvore onde os desenvolvedores manipular diretamente os nós de objeto na árvore para afetam o processamento ou o comportamento de um aplicativo. Windows Presentation Foundation (WPF)também usa vários metáforas de estrutura de árvore para definir relacionamentos entre elementos do programa. Para desenvolvedores WPF parte mais podem criar um aplicativo no código ou definir partes do aplicativo no XAML ao pensar conceitualmente sobre a metáfora da árvore de objeto, mas será chamada de API específica ou usando a marcação específica para fazê-lo em vez de alguns gerais objeto API de manipulação de árvore, como, por exemplo, você pode usar no DOM XML. O WPF expõe duas classes auxiliares que fornecem uma exibição em árvore metáfora, LogicalTreeHelper e VisualTreeHelper. A árvore visual de termos e a árvore lógica também são usados na documentação do WPF, porque essas mesmas árvores são úteis para entender o comportamento de alguns recursos principais do WPF. Este tópico define o que representam a árvore visual e a árvore lógica, discute como tais árvores se relacionam com um conceito geral de árvore de objeto e apresenta LogicalTreeHelper e VisualTreeHelpers

Este tópico contém as seguintes seções.

  • Trees in WPF
  • The Logical Tree
  • The Visual Tree
  • Trees, Content Elements, and Content Hosts
  • Tree Traversal
  • Routes for Routed Events as a "Tree"
  • Árvores e dicionários de recurso
  • Tópicos relacionados

Trees in WPF

A estrutura de árvore mais completa em WPF é a árvore do objeto. Se você definir uma página de aplicativo em XAML e carregue o XAML, a estrutura de árvore é criada com base em relações de aninhamento dos elementos na marcação. Se você define um aplicativo ou uma parte do aplicativo no código, em seguida, a estrutura de árvore é criada com base em como você atribuir valores de propriedade para propriedades que implementam o modelo de conteúdo para um determinado objeto. Em Windows Presentation Foundation (WPF), há duas maneiras que a árvore de objetos completa é conceitualizam e pode ser informada para sua API pública: como a árvore lógica e a árvore visual. The distinctions between logical tree and visual tree are not always necessarily important, but they can occasionally cause issues with certain WPF subsystems and affect choices you make in markup or code.

Embora você não sempre manipular a árvore lógica ou árvore visual diretamente, Noções básicas sobre os conceitos de como as árvores interagem é útil para compreender o WPF como uma tecnologia. Pensando em WPF como uma metáfora da árvore de algum tipo também é crucial para entender como funcionam a herança de propriedade e o roteamento de eventos no WPF.

Observação

Como a árvore de objetos é a mais de um conceito de uma API real, outra maneira de pensar o conceito é como um gráfico de objeto.Na prática, existem relações entre objetos em tempo de execução, onde a metáfora da árvore travará.Todavia, particularmente com interface de usuário definida em XAML, a metáfora da árvore é suficientemente relevante para a maioria dos documentação do WPF usará a árvore de objetos do termo ao fazer referência a esse conceito geral.

The Logical Tree

Em WPF, adicione o conteúdo de elementos de UI, definindo as propriedades dos objetos que pode fazer esses elementos. Por exemplo, você adicionar itens a uma ListBox controle manipulando sua Items propriedade. Fazendo isso, você está colocando os itens para o ItemCollection isto é o Items valor da propriedade. Da mesma forma, para adicionar objetos para um DockPanel, você manipular seu Children valor da propriedade. Aqui, você está adicionando objetos para o UIElementCollection. For a code example, see Como: Adicionar um elemento dinamicamente.

Em Extensible Application Markup Language (XAML), quando você colocar os itens de lista em um ListBox ou controles ou outros elementos de interface do usuário em um DockPanel, você também usar o Items e Children Propriedades, explícita ou implicitamente, como no exemplo a seguir.

<DockPanel
  Name="ParentElement"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >
  <!--implicit: <DockPanel.Children>-->
  <ListBox DockPanel.Dock="Top">
    <!--implicit: <ListBox.Items>-->
    <ListBoxItem>
      <TextBlock>Dog</TextBlock>
    </ListBoxItem>
    <ListBoxItem>
      <TextBlock>Cat</TextBlock>
    </ListBoxItem>
    <ListBoxItem>
      <TextBlock>Fish</TextBlock>
    </ListBoxItem>
  <!--implicit: </ListBox.Items>-->
  </ListBox>
  <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
  <!--implicit: </DockPanel.Children>-->
</DockPanel>

Se foram processar esse XAML como XML em um modelo de objeto de documento, e se você tivesse incluído as marcas comentadas out como implícita (que teria sido legal), a árvore DOM do XML resultante seria ter incluído a elementos de <ListBox.Items> e outro implícito itens. Mas o XAML não processa dessa maneira para a marcação de ler e gravar em objetos, o gráfico do objeto resultante não inclui literalmente ListBox.Items. No entanto, ele tem um ListBox propriedade chamada Items que contém um ItemCollectione que ItemCollection é inicializado mas vazio quando o ListBox XAML é processado. Em seguida, cada elemento de objeto filho existe como conteúdo para o ListBox é adicionado ao ItemCollection pelo chamadas de analisador para ItemCollection.Add. Este exemplo de processamento XAML em uma árvore de objetos é até aparentemente um exemplo onde a árvore do objeto criado é basicamente a árvore lógica.

No entanto, a árvore lógica não é o gráfico inteiro de objetos que existe para seu aplicativo fatorado de interface do usuário em tempo de execução, mesmo com os itens de uma sintaxe implícita de XAML. O principal motivo para isso é visuais e modelos. Por exemplo, considere a Button. Os relatórios de árvore lógica de Button objeto e também sua seqüência Content. Mas há mais a este botão na árvore do objeto de tempo de execução. Em particular, o botão só aparece na tela da forma que faz porque um específico Button o modelo de controle foi aplicado. Os elementos visuais que vêm de um modelo aplicado (como, por exemplo, a definição de modelo Border de cinza escura ao redor do botão visual) não são relatados na árvore lógica, mesmo se você está examinando a árvore lógica durante o tempo de execução (como, por exemplo, manipular um evento de entrada da interface do usuário visível e, em seguida, a árvore lógica de leitura). Para localizar os elementos visuais do modelo, em vez disso, você precisaria examinar a árvore visual.

Para obter mais informações sobre como XAML mapas de sintaxe para o gráfico de objeto criado e a sintaxe implícita em XAML, consulte Sintaxe XAML em detalhes ou Visão geral do XAML (WPF)

The Purpose of the Logical Tree

A árvore lógica existe para que os modelos de conteúdo prontamente podem iterar sobre seus objetos filho possíveis e para que os modelos de conteúdo que podem ser extensíveis. Além disso, a árvore lógica fornece uma estrutura para determinadas notificações, como, por exemplo, quando todos os objetos na árvore lógica são carregados. Basicamente, a árvore lógica é uma aproximação de um gráfico de objeto de tempo de execução no nível do framework, que exclui os elementos visuais, mas é adequada para muitas operações de consulta em relação a composição do próprio tempo de execução do aplicativo.

Além disso, ambas as referências de recurso estáticos e dinâmicos são resolvidas, examinando a árvore lógica para cima Resources coleções no objeto de solicitação inicial e em seguida, continuando a árvore lógica e a verificação de cada FrameworkElement (ou FrameworkContentElement) para outra Resources valor que contém um ResourceDictionary, possivelmente contendo chave. The logical tree is used for resource lookup when both the logical tree and the visual tree are present. Para obter mais informações sobre os dicionários de recurso e de pesquisa, consulte Visão geral sobre Recursos.

Composição de árvore lógica

A árvore lógica é definida no WPF framework-nível, que significa que o elemento base do WPF que é mais relevante para operações de árvore lógica está FrameworkElement ou FrameworkContentElement. No entanto, como você pode ver se você realmente usar o LogicalTreeHelper API, às vezes, a árvore lógica contém nós que são não ambos FrameworkElement ou FrameworkContentElement. Por exemplo, a árvore lógica relata a Text o valor de um TextBlock, que é uma seqüência de caracteres.

Overriding the Logical Tree

Os autores de controle avançado podem substituir a árvore lógica, substituindo a vários APIs que definem como um objeto geral ou um modelo de conteúdo adiciona ou remove os objetos dentro da árvore lógica. For an example of how to override the logical tree, see Como: Override the Logical Tree.

Property Value Inheritance

Property value inheritance operates through a hybrid tree. The actual metadata that contains the Inherits property that enables property inheritance is the WPF framework-level FrameworkPropertyMetadata class. Portanto, o pai que contém o valor original e o objeto filho que herda o valor devem estar FrameworkElement ou FrameworkContentElement, e eles devem ambos ser parte de alguns árvore lógica. No entanto, para propriedades existentes do WPF que oferecem suporte a herança de propriedade, herança de valor da propriedade é capaz de coisas por meio de um objeto intermediários que não esteja na árvore lógica para. Principalmente, isso é relevante para ter elementos de modelo para usar quaisquer valores de propriedade herdada definir tanto a instância de modelo ou em níveis ainda mais altos de composição de nível de página e, portanto, mais alto na árvore lógica. Na ordem de herança de valor de propriedade trabalhar consistentemente em tal um limite, a herança de propriedade deve ser registrada como uma propriedade anexada e você deve seguir esse padrão se você pretende definir uma propriedade de dependência personalizadas com o comportamento da herança de propriedade. The exact tree used for property inheritance cannot be entirely anticipated by a helper class utility method, even at run time. For more information, see Herança de Valor de Propriedade.

The Visual Tree

In addition to the concept of the logical tree, there is also the concept of the visual tree in WPF. A árvore visual descreve a estrutura de objetos visuais, conforme representado pela Visual classe de base. When you write a template for a control, you are defining or redefining the visual tree that applies for that control. The visual tree is also of interest to developers who want lower-level control over drawing for performance and optimization reasons. Uma exposição da árvore visual como parte do convencional WPF a programação de aplicativo é que o evento rotas para um roteados eventos principalmente as viagens ao longo da árvore visual, não a árvore lógica. This subtlety of routed event behavior might not be immediately apparent unless you are a control author. O roteamento de eventos através da árvore visual permite que os controles que implementam composição no nível visual para manipular eventos ou criar setters de eventos.

Trees, Content Elements, and Content Hosts

Content elements (classes that derive from ContentElement) are not part of the visual tree; they do not inherit from Visual and do not have a visual representation. Para aparecer em uma interface de usuário, um ContentElement deve ser hospedado em um host de conteúdo que é um Visual e um participante de árvore lógica. Normalmente, tal objeto é um FrameworkElement. You can conceptualize that the content host is somewhat like a "browser" for the content and chooses how to display that content within the screen region that the host controls. When the content is hosted, the content can be made a participant in certain tree processes that are normally associated with the visual tree. Generally, the FrameworkElement host class includes implementation code that adds any hosted ContentElement to the event route through subnodes of the content logical tree, even though the hosted content is not part of the true visual tree. This is necessary so that a ContentElement can source a routed event that routes to any element other than itself.

Tree Traversal

The LogicalTreeHelper class provides the GetChildren, GetParent, and FindLogicalNode methods for logical tree traversal. Na maioria dos casos, você não deve ter que percorrer a árvore lógica de controles existentes, porque esses controles quase sempre expõem seus elementos filho lógica como uma propriedade de coleção dedicado que suporta o acesso de coleção, como Add, um indexador e assim por diante. Tree traversal is mainly a scenario that is used by control authors who choose not to derive from intended control patterns such as ItemsControl or Panel where collection properties are already defined, and who intend to provide their own collection property support.

The visual tree also supports a helper class for visual tree traversal, VisualTreeHelper. The visual tree is not exposed as conveniently through control-specific properties, so the VisualTreeHelper class is the recommended way to traverse the visual tree if that is necessary for your programming scenario. For more information, see WPF Graphics Rendering Overview.

Observação

Às vezes é necessário examinar a árvore visual de um modelo aplicado.Você deve ter cuidado ao usar essa técnica.Mesmo se você está atravessando a uma árvore visual para um controle onde você define o modelo, os consumidores do seu controle sempre podem alterar o modelo, definindo a Template propriedade em instâncias e até mesmo o usuário final podem influenciar o modelo aplicado alterando o tema do sistema.

Routes for Routed Events as a "Tree"

Como mencionado anteriormente, a rota de evento roteado viaja ao longo de um caminho único e predeterminado de uma árvore que é um híbrido das representações da árvore visual e lógico. A rota de evento pode viajar em cima ou para baixo de direções dentro da árvore dependendo se for tunneling ou bubbling roteados eventos. The event route concept does not have a directly supporting helper class that could be used to "walk" the event route independently of raising an event that actually routes. There is a class that represents the route, EventRoute, but the methods of that class are generally for internal use only.

Árvores e dicionários de recurso

Pesquisa do dicionário de recurso para todas as Resources definido em uma página atravessa basicamente a árvore lógica. Objetos que não estão na árvore lógica podem fazer referência a recursos com chave, mas a seqüência de pesquisa de recurso começa no ponto onde o objeto está conectado à árvore lógica. No WPF, somente os nós de árvore lógica podem ter um Resources propriedade que contém um ResourceDictionary, portanto não há nenhum benefício como percorrer a árvore visual procurando recursos com chave de um ResourceDictionary.

However, resource lookup can also extend beyond the immediate logical tree. Para marcação de aplicativo, a pesquisa de recursos pode então continuar em diante aos dicionários de recurso de nível de aplicativo e valores de sistema e de suporte do tema que são referenciados como propriedades estáticas ou chaves. Themes themselves can also reference system values outside of the theme logical tree if the resource references are dynamic. Para obter mais informações sobre os dicionários de recurso e a lógica de pesquisa, consulte Visão geral sobre Recursos.

Consulte também

Conceitos

Input Overview

WPF Graphics Rendering Overview

Visão geral sobre eventos roteados

Inicialização para elementos do objeto não está em uma árvore de objetos

Arquitetura WPF