这是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. 谷歌浏览器 URL无法访问

    使用谷歌浏览器老是会崩溃,或者访问的时候发现“URL无法访问”等失败的问题,连淘宝都没法访问,这个让人很恼火, 最后在扩展应用那里搜到个URL的redirect,问题解决了,~~发现没有再出现类似问题 ...

  2. 小试---EF5.0入门实例1

    现在做个小练习吧~~~ 第一步:首先新建一个数据库名字为Test;数据库里面只有一个表UserTable 脚本为: USE [master] GO /****** 对象: Database [Test ...

  3. Python: 合并拼接字符串join()| format() | +

    将几个小字符串合并成为一个大的字符串 1如果合并的是一个序列,最快的方式是使用join()方法 >>> parts = ['Is', 'Chicago', 'Not', 'Chica ...

  4. linux常用命令:service 命令

    service命令用于对系统服务进行管理,比如启动(start).停止(stop).重启(restart).查看状态(status)等.相关的命令还包括chkconfig.ntsysv等,chkcon ...

  5. EasyUI+bootsrtap混合前端框架

    EasyUI+bootsrtap混合前端框架 http://www.jeasyui.com/download/index.php用户没有登录前浏览的页面用bootsrtap框架用户登录进去后的商家管理 ...

  6. GitHub+Hexo 搭建个人网站

    GitHub+Hexo 搭建个人网站 转自 https://www.sufaith.com/article/561.html 一.创建GitHub Pages站点 GitHub Pages是一种静态站 ...

  7. C语言程序设计实习报告

    C语言程序设计实习报告 简介 语言实践心得体会范文在科技高度发展的今天,计算机在人们之中的作用越来越突出.而c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此, ...

  8. 20145304 Exp5 MSF基础应用

    20145304 Exp5 MSF基础应用 实验后回答问题 (1)用自己的话解释什么是exploit,payload,encode. exploit是生成或启动已经设置好的攻击程序,获得相应权限.在实 ...

  9. 加强树状数组luogu3368

    暴力树状数组30分,这该怎么办: 知识点回顾 差分数组中 开头结尾改变了值之后 求他的前缀,发现区间内所有数都改变 然后我们做差分树状数组 #include<cstdio> using n ...

  10. C# 读取txt文件内容

    if (!System.IO.File.Exists(@"E:\\111.txt")) { Console.Write("没有找到文件!"); } System ...