Professional Documents
Culture Documents
Trees in WPF
Trees in WPF
.NET Framework 4.5 In many technologies, elements and components are organized in a tree structure where developers directly manipulate the object nodes in the tree to affect the rendering or behavior of an application. Windows Presentation Foundation (WPF) also uses several tree structure metaphors to define relationships between program elements. For the most part WPF developers can create an application in code or define portions of the application in XAML while thinking conceptually about the object tree metaphor, but will be calling specific API or using specific markup to do so rather than some general object tree manipulation API such as you might use in XML DOM. WPF exposes two helper classes that provide a tree metaphor view, LogicalTreeHelper and VisualTreeHelper. The terms visual tree and logical tree are also used in the WPF documentation because these same trees are useful for understanding the behavior of certain key WPF features. This topic defines what the visual tree and logical tree represent, discusses how such trees relate to an overall object tree concept, and introduces LogicalTreeHelper and VisualTreeHelpers This topic contains the following sections. Trees in WPF The Logical Tree The Visual Tree Trees, Content Elements, and Content Hosts Tree Traversal Routes for Routed Events as a "Tree" Resource Dictionaries and Trees Related Topics
Trees in WPF
The most complete tree structure in WPF is the object tree. If you define an application page in XAML and then load the XAML, the tree structure is created based on the nesting relationships of the elements in the markup. If you define an application or a portion of the application in code, then the tree structure is created based on how you assign property values for properties that implement the content model for a given object. In Windows Presentation Foundation (WPF), there are two ways that the complete object tree is conceptualized and can be reported to its public API: as the logical tree and as the visual tree. 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. Even though you do not always manipulate either the logical tree or the visual tree directly, understanding the concepts of how the trees interact is useful for understanding WPF as a technology. Thinking of WPF as a tree metaphor of some kind is also crucial to understanding how property inheritance and event routing work in WPF. Note Because the object tree is more of a concept than an actual API, another way to think of the concept is as an object graph. In practice, there are relationships between objects at run time where the tree metaphor will break down. Nevertheless, particularly with XAML-defined UI, the tree metaphor is relevant enough that most WPF documentation will use the term object tree when referencing this general concept.
In WPF, you add content to UI elements by setting properties of the objects that back those elements. For example, you add items to a ListBox control by manipulating its Items property. By doing this, you are placing items into the
1/5
12/19/13
add items to a ListBox control by manipulating its Items property. By doing this, you are placing items into the ItemCollection that is the Items property value. Similarly, to add objects to a DockPanel, you manipulate its Children property value. Here, you are adding objects to the UIElementCollection. For a code example, see How to: Add an Element Dynamically. In Extensible Application Markup Language (XAML), when you place list items in a ListBox or controls or other UI elements in a DockPanel, you also use the Items and Children properties, either explicitly or implicitly, as in the following example. XAML < D o c k P a n e l N a m e = " P a r e n t E l e m e n t " x m l n s = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m / w i n f x / 2 0 0 6 / x a m l / p r e s e n t a t i o n " x m l n s : x = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m / w i n f x / 2 0 0 6 / x a m l " > < ! i m p l i c i t :< D o c k P a n e l . C h i l d r e n > > < L i s t B o xD o c k P a n e l . D o c k = " T o p " > < ! i m p l i c i t :< L i s t B o x . I t e m s > > < L i s t B o x I t e m > < T e x t B l o c k > D o g < / T e x t B l o c k > < / L i s t B o x I t e m > < L i s t B o x I t e m > < T e x t B l o c k > C a t < / T e x t B l o c k > < / L i s t B o x I t e m > < L i s t B o x I t e m > < T e x t B l o c k > F i s h < / T e x t B l o c k > < / L i s t B o x I t e m > < ! i m p l i c i t :< / L i s t B o x . I t e m s > > < / L i s t B o x > < B u t t o nH e i g h t = " 2 0 "W i d t h = " 1 0 0 "D o c k P a n e l . D o c k = " T o p " > B u yaP e t < / B u t t o n > < ! i m p l i c i t :< / D o c k P a n e l . C h i l d r e n > > < / D o c k P a n e l > If you were to process this XAML as XML under a document object model, and if you had included the tags commented out as implicit (which would have been legal), then the resulting XML DOM tree would have included elements for < L i s t B o x . I t e m s >and the other implicit items. But XAML does not process that way when you read the markup and write to objects, the resulting object graph does not literally include L i s t B o x . I t e m s . It does however have a ListBox property named Items that contains a ItemCollection, and that ItemCollection is initialized but empty when the ListBox XAML is processed. Then, each child object element that exists as content for the ListBox is added to the ItemCollection by parser calls to I t e m C o l l e c t i o n . A d d . This example of processing XAML into an object tree is so far seemingly an example where the created object tree is basically the logical tree. However, the logical tree is not the entire object graph that exists for your application UI at run time, even with the XAML implicit syntax items factored out. The main reason for this is visuals and templates. For example, consider the Button. The logical tree reports the Button object and also its string Content. But there is more to this button in the run-time object tree. In particular, the button only appears on screen the way it does because a specific Button control template was applied. The visuals that come from an applied template (such as the template-defined Border of dark gray around the visual button) are not reported in the logical tree, even if you are looking at the logical tree during run time (such as handling an input event from the visible UI and then reading the logical tree). To find the template visuals, you would instead need to examine the visual tree. For more information about how XAML syntax maps to the created object graph, and implicit syntax in XAML, see XAML Syntax In Detail or XAML Overview (WPF).
Trees in WPF
12/19/13
Trees in WPF
The logical tree exists so that content models can readily iterate over their possible child objects, and so that content models can be extensible. Also, the logical tree provides a framework for certain notifications, such as when all objects in the logical tree are loaded. Basically, the logical tree is an approximation of a run time object graph at the framework level, which excludes visuals, but is adequate for many querying operations against your own run time application's composition. In addition, both static and dynamic resource references are resolved by looking upwards through the logical tree for Resources collections on the initial requesting object, and then continuing up the logical tree and checking each FrameworkElement (or FrameworkContentElement) for another Resources value that contains a ResourceDictionary, possibly containing that key. The logical tree is used for resource lookup when both the logical tree and the visual tree are present. For more information on resource dictionaries and lookup, see XAML Resources.
msdn.microsoft.com/en-us/library/ms753391(d=printer,v=vs.110).aspx
3/5
12/19/13
of conventional WPF application programming is that event routes for a routed event mostly travel along the visual tree, not the logical tree. This subtlety of routed event behavior might not be immediately apparent unless you are a control author. Routing events through the visual tree enables controls that implement composition at the visual level to handle events or create event setters.
Trees in WPF
Tree Traversal
The LogicalTreeHelper class provides the GetChildren, GetParent, and FindLogicalNode methods for logical tree traversal. In most cases, you should not have to traverse the logical tree of existing controls, because these controls almost always expose their logical child elements as a dedicated collection property that supports collection access such as Add, an indexer, and so on. 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. Note Sometimes it is necessary to examine the visual tree of an applied template. You should be careful when using this technique. Even if you are traversing a visual tree for a control where you define the template, consumers of your control can always change the template by setting the Template property on instances, and even the end user can influence the applied template by changing the system theme.
12/19/13
Trees in WPF
Resource dictionary lookup for all Resources defined in a page traverses basically the logical tree. Objects that are not in the logical tree can reference keyed resources, but the resource lookup sequence begins at the point where that object is connected to the logical tree. In WPF, only logical tree nodes can have a Resources property that contains a ResourceDictionary, therefore there is no benefit in traversing the visual tree looking for keyed resources from a ResourceDictionary. However, resource lookup can also extend beyond the immediate logical tree. For application markup, the resource lookup can then continue onward to application-level resource dictionaries and then to theme support and system values that are referenced as static properties or keys. Themes themselves can also reference system values outside of the theme logical tree if the resource references are dynamic. For more information on resource dictionaries and the lookup logic, see XAML Resources.
See Also
Concepts
Input Overview WPF Graphics Rendering Overview Routed Events Overview Initialization for Object Elements Not in an Object Tree WPF Architecture
msdn.microsoft.com/en-us/library/ms753391(d=printer,v=vs.110).aspx
5/5