Compartir a través de


Árboles en WPF

Actualización: noviembre 2007

En muchas tecnologías, los elementos y componentes se organizan en una estructura de árbol que los programadores manipulan directamente para afectar a la representación de una aplicación. Windows Presentation Foundation (WPF) también utiliza varias metáforas de la estructura de árbol para definir las relaciones entre los elementos de programación.

Este tema contiene las secciones siguientes.

  • Árboles en WPF
  • Árbol lógico
  • Árbol visual
  • Árboles, elementos de contenido y hosts de contenido
  • Exploración transversal del árbol
  • Rutas para los eventos enrutados como un "árbol"
  • Recursos y árboles
  • Temas relacionados

Árboles en WPF

La estructura de árbol principal de WPF es el árbol de elementos. Si crea una página de aplicación en XAML, se crea la estructura de árbol basándose en las relaciones del anidamiento de los elementos en el marcado. Si crea una aplicación en código, se crea la estructura de árbol basándose en cómo asigne los valores de las propiedades que implementan el modelo de contenido para un elemento determinado. En Windows Presentation Foundation (WPF), existen en realidad dos maneras de procesar y conceptualizar el árbol de elementos: como el árbol lógico y como el árbol visual. Las distinciones entre árbol lógico y árbol visual no son siempre importantes, pero en ocasiones pueden dar lugar a problemas con algunos subsistemas de WPF y afectar a las opciones que se hacen en marcado o en código.

Aunque no siempre se manipula el árbol lógico o el árbol visual directamente, entender los conceptos relativos a cómo interactúan ayuda a entender cómo funciona la herencia de propiedades y el enrutamiento de eventos en WPF.

Árbol lógico

En WPF, se agrega contenido a los elementos utilizando las propiedades. Por ejemplo, se agregan elementos a un control ListBox mediante su propiedad Items. Al hacerlo, está colocando elementos en la ItemCollection del control ListBox. Para agregar elementos a un control DockPanel, se utiliza su propiedad Children. En este caso, agrega elementos a la UIElementCollection de DockPanel. Para obtener un ejemplo de código, vea Cómo: Agregar dinámicamente un elemento.

En Lenguaje de marcado de aplicaciones extensible (XAML), al colocar los elementos de lista en ListBox, o controles u otros elementos en DockPanel, también se utilizan las propiedades Items y Children, de manera explícita o implícita, como en el ejemplo siguiente.

<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>-->
    <ListItem>
      <Paragraph>Dog</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Cat</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Fish</Paragraph>
    </ListItem>
    <!--implicit: </ListBox.Items>-->
  </ListBox>
  <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>

  <!--implicit: </DockPanel.Children>-->
</DockPanel>

Tenga en cuenta que las etiquetas de elemento de propiedad no se necesitan de forma explícita, porque el lector XAML deduce los elementos de propiedad al crear los objetos que crean la representación de objetos de la aplicación en tiempo de ejecución del ejecutable. Para obtener más información sobre la asignación de la sintaxis XAML al árbol lógico creado, y sobre las etiquetas deducidas, vea Terminología de la sintaxis de XAML o Información general sobre XAML. En el gráfico siguiente se proporciona una vista conceptual del árbol lógico que se construye en tiempo de ejecución (la bifurcación del botón se ha omitido).

Esquema del aspecto de un árbol lógico genérico
Diagrama de árbol

Finalidad del árbol lógico

El árbol lógico existe para que los modelos de contenido puedan recorrer con prontitud en iteración sus posibles elementos secundarios, y para que los modelos de contenido puedan ser extensibles. Asimismo, el árbol lógico proporciona un marco de trabajo para algunas notificaciones, como cuando se han cargado todos los elementos en él.

Además, las referencias de recursos se resuelven buscando en sentido ascendente en el árbol lógico para encontrar las colecciones Resources del elemento de solicitud inicial y, a continuación, los elementos primarios. El árbol lógico se utiliza para la búsqueda de recursos cuando también está presente el árbol visual. Para obtener más información sobre recursos, vea Información general sobre recursos.

Invalidar el árbol lógico

Los autores de controles avanzados pueden invalidar el árbol lógico; para ello, deben invalidar varias API que definen cómo un objeto general o el modelo de contenido agrega o quita elementos en dicho árbol. Para obtener un ejemplo de cómo invalidar el árbol lógico, vea Cómo: Invalidar el árbol lógico.

Herencia de valores de propiedad

La herencia de valores de propiedad funciona a través de un árbol híbrido. Los metadatos reales que contienen la propiedad Inherits que habilita la herencia de propiedades consisten en la clase FrameworkPropertyMetadata de nivel de marco de trabajo de WPF. Por consiguiente, tanto el elemento primario que contiene el valor original como el elemento secundario que hereda deben ser FrameworkElement o FrameworkContentElement, y formar parte de un árbol lógico. Sin embargo, se permite que el árbol lógico de elementos primarios contra elementos secundarios sea disjunto, de tal forma que la herencia de valores de propiedad se pueda perpetuar a través de un elemento visual intermedio que no se encuentre en un árbol lógico. Para que la herencia de valores de propiedad funcione de forma coherente a través de un límite de este tipo, la propiedad que hereda debe registrarse como propiedad asociada. El árbol exacto utilizado para la herencia de propiedad no se puede prever completamente mediante un método de utilidad de clase de aplicación auxiliar, ni siquiera en tiempo de ejecución. Para obtener más información, vea Herencia de valores de propiedad.

Árbol visual

Además del concepto de árbol lógico, en WPF existe el concepto de árbol visual. El árbol visual describe la estructura de objetos visuales representados por la clase base Visual. Cuando se escribe una plantilla para un control, se define o vuelve a definir el árbol visual aplicable a ese control. El árbol visual también reviste interés para los programadores que desean un control de bajo nivel sobre el dibujo por motivos de optimización y rendimiento. Una exposición del árbol visual como parte de la programación de aplicaciones de WPF convencional consiste en que las rutas de evento de un evento enrutado recorren en su mayoría el árbol visual, no el árbol lógico. Esta sutileza de comportamiento de los eventos enrutados puede no resultar patente de forma inmediata salvo para los autores de controles. Enrutar a través del árbol visual permite que los controles que implementan la composición en el nivel visual controlen eventos o creen establecedores de eventos.

Árboles, elementos de contenido y hosts de contenido

Los elementos de contenido (clases que se derivan de ContentElement) no forman parte del árbol visual; no heredan de Visual ni tienen representación visual. Para que aparezcan en la interfaz de usuario, un elemento ContentElement se debe hospedar en un host de contenido que sea un objeto Visual y un elemento del árbol lógico, normalmente un elemento FrameworkElement. Puede considerarse el host del contenido como una especie de "explorador" para el contenido que decide cómo mostrar ese contenido dentro de la zona de la pantalla que controla. Cuando se hospeda el contenido, éste puede participar en algunos procesos del árbol que suelen asociarse al árbol visual. En general, la clase host FrameworkElement incluye código de implementación que agrega cualquier ContentElement hospedado a la ruta del evento a través de subnodos del árbol lógico de contenido, aunque el contenido hospedado no forme parte del verdadero árbol visual. Esto es necesario para que un ContentElement pueda originar un evento enrutado que se enruta a cualquier elemento que no sea él mismo.

Exploración transversal del árbol

La clase LogicalTreeHelper proporciona los métodos GetChildren, GetParent y FindLogicalNode para la exploración transversal del árbol lógico. En la mayoría de los casos, no debería tener que atravesar el árbol lógico de los controles existentes, porque casi siempre exponen sus elementos secundarios lógicos como una propiedad de colección dedicada que admite las API de colección, tales como Add, un indizador, etc. El escenario de exploración transversal del árbol se utiliza principalmente por autores de controles que optan por no derivar de los patrones de control previstos, tales como ItemsControl o Panel donde ya están definidas las propiedades de colección, sino que desean proporcionar su propia compatibilidad con propiedades de colección.

El árbol visual también admite una clase de aplicación auxiliar para su propia exploración transversal, VisualTreeHelper. El árbol visual no se expone de un modo tan cómodo a través de las propiedades específicas del control, por lo que la clase VisualTreeHelper es la manera recomendada de atravesar el árbol visual si fuera necesario en un escenario de programación. Para obtener más información, vea Información general sobre la representación de gráficos en Windows Presentation Foundation.

Rutas para los eventos enrutados como un "árbol"

Como se ha mencionado antes, la ruta de un evento enrutado recorre el árbol de manera efectiva, en sentido ascendente o descendente, según se trate de un evento enrutado de túnel o de propagación. El concepto de ruta de evento no tiene ninguna clase de aplicación auxiliar que lo respalde directamente y que se pueda utilizar para "recorrer" la ruta de evento con independencia de que se provoque un evento que se enrute realmente. Hay una clase que representa la ruta, EventRoute, pero los métodos de esa clase suelen ser sólo para uso interno.

Recursos y árboles

La búsqueda de recursos atraviesa básicamente el árbol lógico. Los objetos que no están en el árbol lógico pueden hacer referencia a recursos, pero la búsqueda se inicia en el punto donde ese objeto está conectado al árbol lógico. Únicamente los nodos de árbol lógico pueden tener una propiedad Resources que contiene ResourceDictionary, de manera que atravesar el árbol visual en busca de recursos no reviste ninguna ventaja.

Sin embargo, la búsqueda de recursos también se puede extender más allá del árbol lógico inmediato. Para el marcado de aplicación, la búsqueda de recursos puede continuar para incluir los recursos de la aplicación, la compatibilidad con temas y los valores de sistema. Los propios temas también pueden hacer referencia a valores del sistema situados fuera del árbol lógico del tema si referencias de recursos son dinámicas. Para obtener más información sobre recursos y la lógica de búsqueda, vea Información general sobre recursos.

Vea también

Conceptos

Información general sobre acciones del usuario

Información general sobre la representación de gráficos en Windows Presentation Foundation

Información general sobre eventos enrutados

Inicialización de elementos de objeto no incluidos en un árbol de elementos

Arquitectura de WPF