WPF的Presenter(ContentPresenter)(转)
这是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的默认容器

先到这里吧
原文链接:http://www.cnblogs.com/Clingingboy/archive/2010/12/20/1911388.html
WPF的Presenter(ContentPresenter)(转)的更多相关文章
- WPF的Presenter(ContentPresenter)
WPF的Presenter(ContentPresenter) 2010-12-20 14:34 by Clingingboy, 10619 阅读, 3 评论, 收藏, 编辑 这是2年前写了一篇文章 ...
- [转]WPF的Presenter(ContentPresenter)
这是2年前写了一篇文章 http://www.cnblogs.com/Clingingboy/archive/2008/07/03/wpfcustomcontrolpart-1.html 我们先来看M ...
- WPF 正確理解ContentPresenter
我們先由下圖來看類層次,可知ContentControl繼承Control,ContentPresenter繼承FrameworkElement(Control也繼承FrameworkElement) ...
- 正确理解ContentPresenter
下图显示继承关系: ContentControl:Control (在Control類並沒有Content屬性, 所以在這之上再寫了一個ContentControl, 使控件有Content屬性可以顯 ...
- WPF仿Word头部格式,涉及DEV RibbonControl,NarvbarControl,ContentPresenter,Navigation
时隔1个月,2015/06/17走进新的环境. 最近一个星期在学习仿Word菜单栏的WPF实现方式,废话不多说,先看一下效果. 打开界面后,默认选中[市场A],A对应的菜单栏,如上图, 选择[市场B] ...
- WPF:为什么使用ContentPresenter.ContentSource而不是Content属性?
因为ContentPresenter.ContentSource比Content属性加一个TemplateBinding看起来更方便?不仅仅是这些,实际上如果用ContentSource的话,Cont ...
- 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)
WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...
- WPF自定义控件第二 - 转盘按钮控件
继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...
- [WPF系列]-基础系列 TabControl应用
引言 Tabcontrol控件也是我们在项目中经常用到的一个控件,用它将相关的信息组织在一起分类显示. 简介 ========================================= ...
随机推荐
- poj.2419.Forests (枚举 + set用法)
Forests Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5782 Accepted: 2218 Descripti ...
- Robberies
Robberies Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit S ...
- Lua中的常用函数库汇总
lua库函数 这些函数都是Lua编程语言的一部分, 点击这里了解更多. assert(value) - 检查一个值是否为非nil, 若不是则(如果在wow.exe打开调试命令)显示对话框以及输出错误调 ...
- 使用python一步一步搭建微信公众平台(一)
使用的工具,python 新浪SAE平台,微信的公众平台 你需要先在微信的公众平台与新浪SAE平台上各种注册,微信平台注册的时候需要你拍张手持身份证的照片,还有几天的审核期 微信公众平台:http:/ ...
- Stanford机器学习---第九讲. 聚类
原文:http://blog.csdn.net/abcjennifer/article/details/7914952 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...
- PHP声明
1. <!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前.2. 此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范. <!DOC ...
- [颓废] 改某人的WebGL light mapping demo并9xSSAA
渲染图(4k) 链接: http://pan.baidu.com/s/1bnB4Wqz 密码: 8839 2px高斯模糊+立方缩小AA: 链接: http://pan.baidu.com/s/1mg ...
- Linux下crontab命令的用法
cron来源于希腊单词chronos(意为“时间”),是linux系统下一个自动执行指定任务的程序.例如,你想在每晚睡觉期间创建某些文件或文件夹的备份,就可以用cron来自动执行. 服务的启动和停止 ...
- 【云计算】Dockerfile示例模板
Dockerfile FROM debian:jessie MAINTAINER "Konrad Kleine" USER root ####################### ...
- string s = null 和 string s = “”的区别
string s = null; 表示一个空串,没有占用了空间,不在内存中开辟空间 string s = "";在内存中开辟空间,但空间中没有值(""也是一个字 ...