这是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. LR和SVM的相同和不同

    之前一篇博客中介绍了Logistics Regression的理论原理:http://www.cnblogs.com/bentuwuying/p/6616680.html. 在大大小小的面试过程中,经 ...

  2. Python:键盘输入input

    从键盘读入数据 >>> num=input('利润是:') 利润是:55 >>>

  3. 彻底明白Flink系统学习5:window、Linux本地安装Flink

    http://www.aboutyun.com/thread-26393-1-1.html 问题导读 1.如何在window下安装Flink? 2.Flink本地安装启动命令与原先版本有什么区别? 3 ...

  4. 使用 Laravel 数据填充生成 中文 测试数据

    Laravel5.4 及更新版本设置了相关的配置项 app.faker_locale,只不过在文档和默认的配置文件中看不到这一参数.相关源码在 Illuminate\Database\Database ...

  5. click 在网页测试手机模式下无效,不能执行。调成非手机模式即可

    click  在网页测试手机模式下无效,不能执行. 调成非手机模式即可

  6. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  7. C/C++之static函数与普通函数

    全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式.这两者在存储方式上并无不同.这两者的区别虽在于非静态全局变量 ...

  8. web前端----css属性

    一.文本 1.文本颜色:color 颜色属性被用来设置文字的颜色. 颜色是通过CSS最经常的指定: 十六进制值 - 如: #FF0000 一个RGB值 - 如: RGB(255,0,0) 颜色的名称 ...

  9. cojs DAG计数问题1-4 题解报告

    最近突然有很多人来问我这些题目怎么做OwO 然而并不是我出的,结论我也不是很懂 研究了一下觉得非常的一颗赛艇,于是就打算写这样一篇题解 DAG 1 我们考虑DAG的性质,枚举出度为0的点 设出度为0的 ...

  10. JavaScript计算星期几

    function zeller(dateStr) { var c = parseInt(dateStr.substr(0, 2)); var y = parseInt(dateStr.substr(2 ...