The existing documentation about the visual tree and logical tree in the Windows SDK leaves much to be desired. Ever since I started with WPF, I have felt unsure about what exactly differentiates the two. Here I will use a simple diagram to make a comparison between them.
<Window>
<Grid>
<Label Content="xuning"/>
<Button>
<TextBlock Text="pfs"/>
</Button>
</Grid>
</Window>
Following is the logical and visual tree of the above xaml codes:
There may be several questions come into your mind after seeing this picture:
- Why those red elements are chosen to be part of logical tree?
The secret is behind a property called LogicalChildren. Panel, ItemsControl, ContentControl, and Decorator, which are the most common base classes, all define this property make the logical tree operate already. For example, if you create a custom Button that subclasses ContentControl, your Content property will pick up your button as the logical parent without you doing anything.
At the end of this article, a table lists the classes that have special support for logical children, and under which property they implement that support.
- Why there is a TextBlock under Label’s visual tree?
Unlike the button, we didn’t declare a TextBlock as the Content of Label, instead we only used a string “Xuning” there. Who created a TextBlock for us? Apparently, it’s created by WPF framework. When WPF starts to render an object, it will first check whether there is a template defined for that type, either control template or data template, if it cannot find one, it will simply call the object’s ToString method and put the return value into a TextBlock.
- Why Label’s logical child is a string?
The element in logical tree doesn’t have to be a UIElement or Visual object, it can be any type. Label is a ContentControl which take its Content property as logical child, here it happens to be string “xuning”.
Related Resources:
Of logical and visual trees in WPF
Understanding the Visual Tree and Logical Tree in WPF
Appendix:
|
Class |
Property(ies) |
|
System.Windows.Controls |
|
|
AdornedElementPlaceholder |
Child property |
|
ContentControl |
Content |
|
Decorator |
Child |
|
Grid |
Children (inherited from Panel), Columns, Rows |
|
HeaderedContentControl |
Content (inherited from ContentControl), Header |
|
HeaderedItemsControl |
Items (inherited from ItemsControl), Header |
|
InkCanvas |
Children |
|
ItemsControl |
Items |
|
Page |
Content |
|
Panel |
Children |
|
RichTextBox |
Document |
|
TextBlock |
Text |
|
TextBox |
Text |
|
ToolBarTray |
ToolBars |
|
ViewBox |
Child |
|
System.Windows.Controls.Primitives |
|
|
BulletDecorator |
Bullet and Child |
|
DocumentViewerBase |
Document |
|
Popup |
Child |
|
System.Windows.Documents |
|
|
FixedDocument |
Pages |
|
FixedPage |
Children |
|
FlowDocument |
Blocks |
|
FlowDocumentReader |
Document |
|
FlowDocumentScrollViewer |
Document |
|
PageContent |
Child |
|
Table |
RowGroups, Columns |
|
Span |
Inlines |
浙公網安備 33010602011771號