这是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. 正确理解ContentPresenter

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

  2. WPF 正確理解ContentPresenter

    我們先由下圖來看類層次,可知ContentControl繼承Control,ContentPresenter繼承FrameworkElement(Control也繼承FrameworkElement) ...

  3. 《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架

    <深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的 ...

  4. [WP8.1UI控件编程]Windows Phone理解和运用ItemTemplate、ContentTemplate和DataTemplate

    2.2.5 ItemTemplate.ContentTemplate和DataTemplate 在理解ItemTemplate.ContentTemplate和DataTemplate的关系的之前,我 ...

  5. WPF的Presenter(ContentPresenter)(转)

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

  6. ContentPresenter

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

  7. WPF的Presenter(ContentPresenter)

    WPF的Presenter(ContentPresenter) 2010-12-20 14:34 by Clingingboy, 10619 阅读, 3 评论, 收藏, 编辑 这是2年前写了一篇文章 ...

  8. [转]WPF的Presenter(ContentPresenter)

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

  9. 理解WPF中的视觉树和逻辑树

    轉載地址:http://blog.csdn.net/changtianshuiyue/article/details/26981797 理解WPF中的视觉树和逻辑树  Understanding th ...

随机推荐

  1. Java实现一致性Hash算法

    Java代码实现了一致性Hash算法,并加入虚拟节点.,具体代码为: package com.baijob.commonTools;   import java.util.Collection; im ...

  2. OpenJudge 东方14ACM小组 / 20170123 06:Challenge 3

    总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  262144kB 描述 给一个长为N的数列,有M次操作,每次操作是以下两种之一: (1)修改数列中的一个数 (2)求 ...

  3. 【CF652C】Foe Pairs(线性扫描)

    题意:给你1-n的一个排列和m组数对,问有多少区间不包含任意一个数对. (1 ≤ n, m ≤ 3·105) 思路:数据范围过大,不能用容斥原理 f[i]表示以位置i上的数为左端点,右端点最小到哪里 ...

  4. JS中使用EL表达式方法与获取工程名字

    关键: 在js中使用el表达式一定要使用双引号      分两种情况 1. JS代码在JSP页面中, 这可以直接使用EL表达式. 如: <script type="text/javas ...

  5. Sphinx的GEO距离搜索 [转载]

    近项目用sphinx做地理搜索,可是结果总是不对,明明很近却搜不到 结果检查sphinx源文件: static inline double sphSqr ( double v ) { return v ...

  6. hdu 5443(线段树水)

    The Water Problem Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  7. LeetCode OJ--Remove Duplicates from Sorted Array

    http://oj.leetcode.com/problems/remove-duplicates-from-sorted-array/ 删除数组中的重复元素,要求为原地算法. 进行一遍遍历,记录下一 ...

  8. 小程序-TabBar点击切换

    这种页面的布局会经常用到,所以在此做个笔记,之后遇到可以节省很多时间 WXML: <view class='listTitle_tab'>      <view class='scr ...

  9. SD-WAN用户实践分享:老网工趟出的SD-WAN成功路

    在这个离开“人大物云”(人-人工智能.大-大数据.物-物联网.云-云计算)话题都张不开嘴的年代,在这个在咖啡店谈生意都不好意思低于1个亿的年代,反思我的老本行——网络,正在以一种全新的.更加重要的姿态 ...

  10. SSL剥离工具sslstrip

    SSL剥离工具sslstrip   在日常上网过程中,用户只是在地址栏中输入网站域名,而不添加协议类型,如HTTP和HTTPS.这时,浏览器会默认在域名之前添加http://,然后请求网站.如果网站采 ...