WPF——ContentPresenter
文章目录一、前言二、认识2.1. 涉及名词释义2.2. 定义2.3. 例子2.4. 注解*一、前言 ~~~~ 这个类单独拿出来讲,是因为它既很重要又很迷惑。说重要是因为一般DataTemplate的载体(作用对象)就是它,而且你用MSBlend敲开一个控件你会发现每每都存在它。说迷惑是因为,你在相关类的属性
一、前言
这个类单独拿出来讲,是因为它很重要,但又很迷惑,很多人可能都不知道它。说重要是因为一般DataTemplate的载体(作用对象)就是它,而且你用Blend for VS敲开一个控件,你会发现每每都存在它。说迷惑是因为,你在相关类的属性中发现不了它。
二、认识
2.1 涉及名词释义
涉及的部分英语单词,后面用中文叫了。
英文名称 | 中文译名 | 是什么? |
---|---|---|
ContentControl | 内容控件 | class |
DataTemplate | 数据模板 | class |
ControlTemplate | 控件模板 | class |
ContentPresenter | 内容呈现器 | class |
Template | 控件模板 | Control类中ControlTemplate类型的属性 |
ContentTemplate | 内容模板 | ContentControl中DataTemplate类型的属性 |
Notes:
所以后面说Template就是指Control类中ControlTemplate类型的属性,即ControlTemplate Template
ContentTemplate是指ContentControl类中DataTemplate类型的属性,
两者区别就是,Template时指的是Control中的属性,ControlTemplate指类,
ContentTemplate与DataTemplate同理。
2.2 定义
也不花里胡哨,直接看看官方文档的定义。
作用言简意赅,用于呈现ContentControl的Content,即显示内容控件的内容。
下面是ContentPresenter类的继承关系类图,特别注意其属性,它只有ContentTemplate属性,没有Template属性,这就说明了它的用途必定与DataTemplate有关。
2.3 例子
下面展示一个按钮的样式,该样式设置了Button的ControlTemplate。该ControlTemplate定义了一个在Grid元素内部的椭圆形按钮。ContentPresenter标记了按钮应被呈现,且位于Grid中水平垂直居中。
下面是其XAML,
<Style TargetType="Button">
<!--值设为true,使其不从主题中获取任何属性-->
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
主窗体中添加一个按钮,
<Grid>
<Button Content="Content" Background="LightBlue"/>
</Grid>
效果如下图,你的按钮改变了外观。
此时,你若把ContentPresenter注释掉,
<!--ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/-->
运行效果如下,
Button中的内容就不显示了,至此,ContentPresenter这个名词也非常好理解了,就是内容呈现器——字面意思,用于呈现内容的。
⭐2.4 附注
通常,会使用ContentPresenter在一个ContentControl的ContentTemplate属性中来指定内容添加的位置。 每个ContentControl类型的默认控件模板中都会有一个ContentPresenter(来呈现ContentControl的内容)。
当一个ContentPresenter对象位于ContentControl的ControlTemplate中时,该对象的Content,ContentTemplate以及ContentTemplateSelector属性会从ContentControl中的相同名称的属性中取得值(就如2.3例子的情况)。(从下面继承关系的类图可知,ContentControl和ContentPresenter中都有一个ContentTemplate属性,意思就是ContentPresenter的ContentTemplate会使用ContentControl的ContentTemplate数据)
你可以通过设置ContentSource属性或者绑定的方式来让ContentPresenter属性从其他的模板化父亲(Templated Parent)的属性中获取值。
~~~~
ContentPresenter使用以下的逻辑来显示Content内容(流水账,看懂两个就好):
- 如果已经设置了ContentPresenter中的ContentTemplate属性,ContentPresenter会将这个DataTemplate(指的就是ContentTemplate)应用到Content属性上并且显示作为结果的UIElement和它的子元素(将DataTemplate内的控件树显示)。
- 若设置了ContentTemplateSelector,ContentPresenter就会将合适的DataTemplate应用到Content上并显示作为结果的UIElement和它的子元素。
- 若有DataTemplate关联到Content,ContentPresenter会将DataTemplate应用到Content上并且显示UIElement和子元素。。
- 若Content是UIElement对象,UIElement就会被呈现。若UIElement已经有一个父亲,会产生一个异常。
- 若有一个用于将Content转化为UIElement的TypeConverter,ContentPresenter就会用这个TypeConverter并呈现UIElement。
- 若有一个用于将Content转化为string的TypeConverter,ContentPresenter就会用这个TypeConverter并创建一个TextBlock来容纳那段string,接着TextBlock会被显示。
- 若内容是XmlElement,InnerText属性的值会显示在TextBlock中
- ContentPresenter在Content上调用ToString方法并创建一个TextBlock来容纳这个ToString返回的string。接着TextBlock被显示。
三、参考
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)