这是2年前写了一篇文章

http://www.cnblogs.com/Clingingboy/archive/2008/07/03/wpfcustomcontrolpart-1.html

我们先来看MSDN对其的介绍

Displays the content of a ContentControl

似乎其是为ContentControl定身量做的.

为了理解这一点,首先我们要对WPF内容模型有所了解,上面这篇文章有提到过ContentControl继承自Control,多了Content属性,继承自ContentControl的均可以称之为内容模型的控件.如下

这里似乎看不到ContentPresenter的影子.下面来举一些例子

一个ContentPresenter的例子

ContentPresenter可以直接在xaml中输出,其视觉树中包含一个TextBlock,在默认的WPF样式定义中找不到任何关于ContentPresenter的样式,说明了ContentPresenter并非是真正代码逻辑与样式分离的,而是在内部代码中提供了一个默认的模板即呈现了TextBlock,如果在内部创建模板的话,一般均会采用FrameworkElementFactory创建根元素,但这种方式太过于复杂,适用于一些简单默认操作,就如ContentPresenter内部的TextBlock.

那么问题出来了,为什么不直接用TextBlock呢,还要包装一个ContentPresenter?

ContentPresenter与TextBlock

如要回答上面的问题,那么就犹如来讨论两者的区别,我们来看下TextBlock

<TextBlock Text="Hello"/>

TextBlock是一个真正以文字为主题的元素,而ContentPresenter的功能就不只呈现文字了(只补)

只不过默认是呈现文字而已,但两者概念完全不同,Content属性是object类型,而非string,可以自己以Content为数据源而重新定义模板(ContentTemplate),如下示例

这样的话ContentPresenter将不再局限于文字的呈现.

下面来看看ContentControl与ContentPresenter的关系

ContentControl与ContentPresenter

先看一个被重新定义的的Button样式

上面可以看到,使用ContentPresenter非常的方便,只要将ContentPresenter放在模板中即可,也不需要做任何的额外的绑定(难道不需要做吗?只不过ContentPresenter内部帮我们做了默认的绑定),但如果使用TextBlock呢?如下还是需要做绑定的

        <Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock Text="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

如上看来我们还不如说ContentControl是ContentPresenter的一个特例,而ContentPresente

ContentPresenter则是ContentControl的基础.为了适配ContentPresenter,ContentControl提供了内容模型的相关属性,本质上ContentPresenter并非仅仅只是用到ContentControl而已,ContentPresenter可以通过指定ContentSource来绑定指定的源属性

记住内容模型不仅仅只是呈现文字而已,如果只是为了呈现文字的话,是不需要ContentPresenter的

父子元素之间的关系(ItemsPresenter)

有时候控件并非维护本身逻辑,而是依赖于父子元素的,如了上诉的ContentPresenter,我们还有一个非常常用的ListBox控件,因为继承自ItemsControl,所以有一个ItemsPanel属性作为集合元素承载容器,但集合控件本身却不负责呈现控件,那么这个任务就留给了子元素ItemsPresenter,其实用也很简单,只要把ItemsPresenter放在内部模板中,那么ItemsPresenter则会去检测父元素是否为集合控件,然后将ItemsPanel添加到其内部视觉树当中

        <Style x:Key="{x:Type ItemsControl}"
TargetType="{x:Type ItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

如下视觉树,StackPanel作为ItemsControl的默认容器

先到这里吧

ContentPresenter的更多相关文章

  1. ContentControl与ContentPresenter区别?

    <TextBlock HorizontalAlignment="Left" Text="{Binding HwContent, Converter={StaticR ...

  2. WPF仿Word头部格式,涉及DEV RibbonControl,NarvbarControl,ContentPresenter,Navigation

    时隔1个月,2015/06/17走进新的环境. 最近一个星期在学习仿Word菜单栏的WPF实现方式,废话不多说,先看一下效果. 打开界面后,默认选中[市场A],A对应的菜单栏,如上图, 选择[市场B] ...

  3. WPF的Presenter(ContentPresenter)(转)

    这是2年前写了一篇文章 http://www.cnblogs.com/Clingingboy/archive/2008/07/03/wpfcustomcontrolpart-1.html 我们先来看M ...

  4. 正确理解ContentPresenter

    下图显示继承关系: ContentControl:Control (在Control類並沒有Content屬性, 所以在這之上再寫了一個ContentControl, 使控件有Content屬性可以顯 ...

  5. 重新想象 Windows 8 Store Apps (3) - 控件之内容控件: ToolTip, Frame, AppBar, ContentControl, ContentPresenter; 容器控件: Border, Viewbox, Popup

    原文:重新想象 Windows 8 Store Apps (3) - 控件之内容控件: ToolTip, Frame, AppBar, ContentControl, ContentPresenter ...

  6. [UWP]为什么ContentControl的ControlTemplate里放两个ContentPresenter会出问题(绕口)

    1. 简单的HeaderedContentControl 上周五收到反馈,在一个ContentControl的ControlTemplate中放两个ContentPresenter会出错.出错的例子是 ...

  7. ContentControl as CC和ContentPresenter as CP的使用

    1.CC为文本控件的父类,它继承为control,所以他是控件, 2.CP继承FrameworkElement,所以他是容器,相当于占位符 3.想让控件中能包含子控件就需要用CP,反之用CC就行.(不 ...

  8. 背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter

    [源码下载] 背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter 作者:weba ...

  9. ContentPresenter元素

    一个内容控件 分解它的“结构树”,肯定能够看到ContentPresenter“元素”,该元素的功能:用来为“内容控件”显示“Content”

随机推荐

  1. Postman: Pre-request Script,设置body 变量

    1)Postman Pre-request Script 设置变量名 2)把变量放在body里 3)Send后查看变量是否被替换

  2. Linux下的Make命令实例详解

    众所周知在Linux系统下的make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.下面这 篇文章我们将用一 ...

  3. Ubuntu系统下使用Jenkins进行项目的自动构建还是项目回滚方法

    上面虽然实现了项目的自动部署,但是有时部署失败的时候我们需要回滚到指定版本的构建,这样才能更灵活的进行项目的构建部署.我们可以选择“参数化的构建过程”进行传递不同的参数来选择是进行新的构建还是回滚 如 ...

  4. C站投稿映兔源的方法

    (因映兔源也不太稳定了,所以不建议映兔上传,正在找其他视频源代替映兔,另外等待C站大大们的webbt源)(20180226) 测试换文件格式后会不会失效,能坚持几天?http://www.cnblog ...

  5. Java实现Sybase数据库连接

    Java实现Sybase数据库连接 需要的jar包:jconn4.jar: Java代码: /** * @Title: getConnSybase * @Description: * @param * ...

  6. CP2102

    1概述 CP2102其集成度高,内置USB2.0全速功能控制器.USB收发器.晶体振荡器.EEPROM及异步串行数据总线(UART),支持调制解调器全功能信号,无需任何外部的USB器件.CP2102与 ...

  7. Spring Boot条件注解

    一.为什么SpringBoot产生于Spring4? Spring4中增加了@Condition annotation, 使用该Annotation之后,在做依赖注入的时候,会检测是否满足某个条件来决 ...

  8. 【入门教程】kafka环境搭建以及基础教程

    问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有 ...

  9. require的shim解释

    通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim,shim解释起来也比较难理解,shim直 ...

  10. Netty原理剖析

    1. Netty简介 Netty是一个高性能.异步事件驱动的NIO框架,基于JAVA NIO提供的API实现.它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作 ...