您的位置:首页 > 编程语言 > PHP开发

正确理解ContentPresenter

2013-09-30 11:13 316 查看
下图显示继承关系:

ContentControl:Control(在Control類並沒有Content屬性,所以在這之上再寫了一個ContentControl,使控件有Content屬性可以顯示內容)

ContentPresenter:FrameworkElement(ContentPresenter一般用在CT里负责把Control指定的Content显示出来)

Control:FrameworkElement

ItemsControl:Control

ItemsPresenter:FrameworkElement





接著來我們看一下實例:

使用ContentPresenter

<ContentControlContent="YangMark">
<ContentControl.Template>
<ControlTemplateTargetType="ContentControl">
<ContentPresenter/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>

輸出結果:YangMark

正確顯示Content!!


不使用ContentPresenter


<ContentControlContent="YangMark">
<ContentControl.Template>
<ControlTemplateTargetType="ContentControl">
              <ContentPresenter/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>


輸出結果:

無法顯示出Content!!

結論1:ContentPresenter通常出現在ControlTemplate內,且若不使用ContentPresenter則Content屬性就無法正常顯示。


實例2:ContentPresenter中的ContentSource屬性

為什麼只為了顯示出Content屬性要大費周張弄出ContentPresenter呢??

我們可以先比較以下兩種代碼不同之類,


<ContentControlContent="YangMark"ContentStringFormat="Hello!!{0}">
<ContentControl.Template>
<ControlTemplateTargetType="ContentControl">
<ContentPresenterContentSource="Content"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>


輸出結果:Hello!!YangMark

<ContentControlContent="YangMark"ContentStringFormat="Hello!!{0}">
<ContentControl.Template>
<ControlTemplateTargetType="ContentControl">
<ContentPresenterContent="{TemplateBindingContent}"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>


輸出結果:YangMark

僅出現Content屬性的內容!!


結論2:<ContentPresenter/>與<ContentPresenterContentSource="Content"/>意義上是相同的。

写ContentSource它們同時綁定了Content,ContentStringFormat,ContentTemplate和ContentTemplateSelector等內容

若僅用Content="{TemplateBindingContent}"代表只綁定Content屬性而已,还要手动绑定其他ContentStringFormat,ContentTemplate和ContentTemplateSelector等。

實例3:ContentSource的應用

以HeaderContentControl為例,使用ContentPresenter綁定內容屬性。


<HeaderedContentControlHeader="Header"HeaderStringFormat="I'm{0}"
Content="Content"ContentStringFormat="I'm{0}">
<HeaderedContentControl.Template>
<ControlTemplateTargetType="HeaderedContentControl">
<DockPanel>

<ContentPresenterContentSource="Header"DockPanel.Dock="Top"></ContentPresenter>

<!--等同於<ContentPresenterContentSource="Content"/>-->
<ContentPresenter></ContentPresenter>

</DockPanel>
</ControlTemplate>
</HeaderedContentControl.Template>
</HeaderedContentControl>


輸出結果:

I'mHeader

I’mContent

結論3:ContentSource若指定對象為Content是可以省略的,若不為Content(如:Header)則不能省略。

總結:

Content,ContentStringFormat,ContentTemplate和ContentTemplateSelector等屬性,我將它們稱為內容屬性.

1.ContentPresenter的作用就是用來顯示內容屬性

2.ContentSource若指定對象為Content,則等同於<ContentPresenter/>;若指定對象不為Content,

則必須使用ContentSource聲明指定的對象.

參考資料:

比如使用ContentPresenter的ContentSource,然后在ContentControl中设置ContentStringFormat:

<Window.Resources>

<StyleTargetType="ContentControl">

<SetterProperty="Template">

<Setter.Value>

<ControlTemplateTargetType="ContentControl">

<!--这里等价于直接<ContentPresenter/>-->

<!--强调一下直接用ContentPresenter其ContentSource属性为Content-->

<ContentPresenterContentSource="Content"/>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</Window.Resources>

<ContentControlContentStringFormat="你好:{0}">Mgen</ContentControl>

结果会输出:你好:Mgen。

如果把上面ContentPresenter改用TemplateBinding绑定ContentControl的Content属性:

<ContentPresenterContent="{TemplateBindingContent}"/>

结果只会输出:Mgen。

此时其实ContentStringFormat,ContentTemplate和ContentTemplateSelector都不会管用的,那么只能再用TemplateBinding都把他们在ContentPresenter中绑定好:

<ContentPresenterContent="{TemplateBindingContent}"

ContentStringFormat="{TemplateBindingContentStringFormat}"

ContentTemplate="{TemplateBindingContentTemplate}"

ContentTemplateSelector="{TemplateBindingContentTemplateSelector}"/>

当然ContentPresenter不仅限于ContentControl,可以用在任何类似ContentControl.Content这样的控件属性中,比如HeaderedContentControl.Header属性。

这样定义HeaderedContentControl的控件模板:

<StyleTargetType="HeaderedContentControl">

<SetterProperty="Template">

<Setter.Value>

<ControlTemplateTargetType="HeaderedContentControl">

<DockPanel>

<BorderDockPanel.Dock="Top">

<ContentPresenterContentSource="Header"/>

</Border>

<!--等于:<ContentPresenterContentSource="Content"/>-->

<ContentPresenter/>

</DockPanel>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

示例:

<HeaderedContentControlHeader="Header"

Content="Content"

HeaderStringFormat="上:{0}"

ContentStringFormat="下:{0}"/>

结果:





如果用Content来绑定Header属性:

<ContentPresenterContent="{TemplateBindingHeader}"/>

那么你还得再次绑定ContentStringFormat,ContentTemplate和ContentTemplateSelector属性,所以记住总是用ContentPresenter.ContentSource属性。

WPF:为什么使用ContentPresenter.ContentSource而不是Content属性?

wpf控件开发基础(1)

转WPF的Presenter(ContentPresenter)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: