(Note: Logical trees are called logical trees in Chinese, and visual trees are called visual trees in Chinese. Because the names are not uniform, the English names are used to represent the two concepts, besides, visualtreehelper and logicaltreehelper are also the class names provided by WPF. As we all know, the logical tree in WPF is a logically defined element hierarchy tree, while the element hierarchy tree actually displayed on the screen is a visual tree, visual tree is
(Note: Logical trees are called logical trees in Chinese, and visual trees are called visual trees in Chinese. Because the names are not uniform, the English names are used to represent the two concepts, besides, visualtreehelper and logicaltreehelper are also the class names provided in WPF)
As we all know, the logical tree in WPF is a logically defined element hierarchy tree. In fact, the element hierarchy tree displayed on the screen is a visual tree, and the visual tree is the product after the expansion of the logical tree node. Therefore, from the perspective of visual tree (visual tree is of course a complete one), the logical tree is divided into segments, and the connection points between these segments are related to templatedparent.
In the WPF model, this concept is the frameworkelement. templatedparent attribute. The template (Data Template and control template) in WPF can both extend the logical tree, so the object modified by the template is the templatedparent of the elements in the template, in this case, the template element and modifier object will appear in the visual tree, but the template element certainly does not belong to the logical tree of the modifier element, but the template has its own logical tree, the two logical trees are separated, but there is a link between them through templatedparent.
Let's look at the sample code below:
This is a simple contentcontrol. Its content is a button, and the control template and data template are defined. Some key elements in the Code include the name attribute, we will reference these elements with the value of the name attribute in subsequent discussions.
<Contentcontrol name = "contentcontrol">
<! -- Control template -->
<Contentcontrol. template>
<Controltemplate targettype = "contentcontrol">
<Border name = "bd1">
<Contentpresenter name = "CP1" contentsource = "content"/>
</Border>
</Controltemplate>
</Contentcontrol. template>
<! -- Data Template -->
<Contentcontrol. contenttemplate>
<Datatemplate>
<Border name = "bd2">
<Contentpresenter name = "CP2" content = "{binding}"/>
</Border>
</Datatemplate>
</Contentcontrol. contenttemplate>
<! -- Logical child -->
<Button name = "BTN"> button </button>
</Contentcontrol>
The visual tree of contentcontrol is as follows:
Nodes of the same color in the figure belong to the same logical tree. It can be seen that the entire visual tree is divided into multiple logical trees, which are separated, for example, in the preceding code, the two border names are bd1 and bd2, and their parent attribute values are null, that is, there is no logical parent node. However, these logical trees are related to each other through templatedparent. For example, the templatedparent of the element in the control template refers to the top contentcontrol, while the templatedparent of the Data Template element is the contentpresenter element in the control template.
The code can also verify that: (bd1, bd2, CP1, CP2 represent the border and contentpresenter in the control template and data template respectively)
Private void button_click (Object sender, routedeventargs E)
{
VaR bd1 = (Border) contentcontrol. template. findname ("bd1", contentcontrol );
VaR CP1 = (contentpresenter) contentcontrol. template. findname ("CP1", contentcontrol );
VaR bd2 = (Border) contentcontrol. contenttemplate. findname ("bd2", CP1 );
VaR CP2 = (contentpresenter) contentcontrol. contenttemplate. findname ("CP2", CP1 );
Printinfo (bd1, CP1, bd2, CP2, BTN );
}
Void printinfo (Params frameworkelement [] eles)
{
String S = "";
Foreach (VAR ele in eles)
S + = string. format ("{2} \ r \ nparent: {0} \ r \ ntemplatedparent: {1} \ r \ n", ELE. parent, ELE. templatedparent, ELE. name );
MessageBox. Show (s );
}
Output Information: (null if there is no value after the colon)
Bd1
Parent:
Templatedparent: system. Windows. Controls. contentcontrol: button
CP1
Parent: system. Windows. Controls. Border
Templatedparent: system. Windows. Controls. contentcontrol: button
Bd2
Parent:
Templatedparent: system. Windows. Controls. contentpresenter
CP2
Parent: system. Windows. Controls. Border
Templatedparent: system. Windows. Controls. contentpresenter
BTN
Parent: system. Windows. Controls. contentcontrol: button
Templatedparent:
Finally, there is a BTN, which refers to the content button in contentcontrol, which belongs to the trunk logic tree. Therefore, parent is contentcontrol and does not belong to any template and does not contain any modifier object. Therefore, templatedparent is null.
In addition, the WPF Data Binding binding class also supports the relativesource object. The mode attribute of this relativesource class has a templatedparent value, which indicates that the data binding will act as the data source, at the same time, the templatebinding tag extension in WPF can easily define such bindings. In addition, the binding mode of templatebinding is oneway.
After learning about templatedparent, It is very flexible to use templatebinding. In general, templatebinding can be used in the definition control template, but also in the data template. For example:
<Contentcontrol>
<Button> content </button>
<Contentcontrol. contenttemplate>
<Datatemplate>
<Contentpresenter content = "{templatebinding content}"/>
</Datatemplate>
</Contentcontrol. contenttemplate>
</Contentcontrol>
Where is the templatebinding data source? The answer is contentpresenter in the default control template in contentcontrol. Therefore, the content of contentpresenter in the data template is directly bound to the content attribute of contentpresenter in the control template. Of course, this is only for example, you can also use content = "{binding.
This article from Liu Yuanyuan's blog, original address: http://www.cnblogs.com/mgen/archive/2011/08/31/2160581.html