因为ContentPresenter.ContentSource比Content属性加一个TemplateBinding看起来更方便?不仅仅是这些,实际上如果用ContentSource的话,Content相关的属性比如ContentStringFormat,ContentTemplate和ContentTemplateSelector都会被自动设置,而如果用Content加TemplateBinding,你必须手动将上述属性绑定到ContentPresenter上。
比如使用ContentPresenter的ContentSource,然后在ContentControl中设置ContentStringFormat:
<Window.Resources>
<Style TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<!-- 这里等价于直接<ContentPresenter /> -->
<!-- 强调一下直接用ContentPresenter其ContentSource属性为Content -->
<ContentPresenter ContentSource="Content"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<ContentControl ContentStringFormat="你好:{0}">Mgen</ContentControl>
结果会输出:你好:Mgen。
如果把上面ContentPresenter改用TemplateBinding绑定ContentControl的Content属性:
结果只会输出:Mgen。
此时其实ContentStringFormat,ContentTemplate和ContentTemplateSelector都不会管用的,那么只能再用TemplateBinding都把他们在ContentPresenter中绑定好:
<ContentPresenter Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
当然ContentPresenter不仅限于ContentControl,可以用在任何类似ContentControl.Content这样的控件属性中,比如HeaderedContentControl.Header属性。
这样定义HeaderedContentControl的控件模板:
<Style TargetType="HeaderedContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedContentControl">
<DockPanel>
<Border DockPanel.Dock="Top">
<ContentPresenter ContentSource="Header"/>
</Border>
<!-- 等于:<ContentPresenter ContentSource="Content"/> -->
<ContentPresenter/>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
示例:
<HeaderedContentControl Header="Header"
Content="Content"
HeaderStringFormat="上:{0}"
ContentStringFormat="下:{0}"/>
结果:
如果用Content来绑定Header属性:
那么你还得再次绑定ContentStringFormat,ContentTemplate和ContentTemplateSelector属性,所以记住总是用ContentPresenter.ContentSource属性。