WPF ContentControl与ContentPresenter 知识积攒

WPF ContentControl与ContentPresenter

Answer one

ContentControl is a base class for controls that contain other elements and have a Content-property (for example, Button).

ContentPresenter is used inside control templates to display content.

ContentControl, when used directly (it’s supposed to be used as a base class), has a control template that uses ContentPresenter to display it’s content.

My rules of thumb (not applicable in every case, use your judgment):

  1. Inside ControlTemplate use ContentPresenter
  2. Outside of ControlTemplate (including DataTemplate and outside templates) try not to use any of them, if you need to, you must prefer ContentPresenter
  3. Subclass ContentControl if you are creating a custom “lookless” control that host content and you can’t get the same result by changing an existing control’s template (that should be extremely rare).

Answer Two

ContentPresenter is usually used in a ControlTemplate, as a placeholder to say “put the actual content here”.

A ContentControl can be used anywhere, not necessarily in a template. It will pick up any DataTemplate defined for the type of content assigned to it

总结

ContentControl类的目的是为了将Content的内容显示在wpf窗体。那没有了ConentControl类,我们就不能将内容显示在wpf窗体上了吗?或者问ContentControl类的Content是如何显示在wpf窗体上的呢?
这里我们就需要知道ContentPresenter类的作用是将ContentControl类的Content显示在wpf窗体,ContentPresenter的作用就是显示内容(Content)。

ContentPresenter 是一个内容呈现模板,

  • 特点1

做模板时,如果对于内容(Content)属性可以不用绑定。

将ContentPresenter放在模板中即可,也不需要做任何的额外的绑定(难道不需要做吗?只不过ContentPresenter内部帮我们做了默认的绑定如下:

一般元素做模板,需要绑定“Content属性”

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

ContentPresenter模板,不需要

		<Style TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <ContentPresenter/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
  • 扩展

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值