WPF:为什么使用ContentPresenter.ContentSource而不是Content属性?
2017-04-13 10:55
357 查看
因为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属性:
<ContentPresenter Content="{TemplateBinding 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属性:
<ContentPresenter Content="{TemplateBinding Header}"/>
那么你还得再次绑定ContentStringFormat,ContentTemplate和ContentTemplateSelector属性,所以记住总是用ContentPresenter.ContentSource属性。
比如使用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属性:
<ContentPresenter Content="{TemplateBinding 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属性:
<ContentPresenter Content="{TemplateBinding Header}"/>
那么你还得再次绑定ContentStringFormat,ContentTemplate和ContentTemplateSelector属性,所以记住总是用ContentPresenter.ContentSource属性。
相关文章推荐
- WPF:为什么使用ContentPresenter.ContentSource而不是Content属性?
- 为什么delegate属性使用delegate而不是retain?
- iOS 面试题(九):为什么block要使用copy而不是strong或者其他属性修饰?
- 为什么delegate属性使用delegate而不是retain?
- 为什么delegate属性使用assign而不是retain?
- 为什么delegate属性使用assign而不是retain?
- 为什么delegate属性使用assigne而不是retain?
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
- 为什么delegate属性使用assign而不是retain?
- 《Effective C#中文版:改善C#程序的50种方法》——Effective C# 原则1:尽可能的使用属性(property),而不是数据成员(field)
- WPF中Image控件的Source属性
- Effective C# 原则1:尽可能的使用属性(property),而不是数据成员(field)
- WPF (当 ItemsSource 正在使用时操作无效。改用 ItemsControl.ItemsSource 访问和修改)错误解决方案
- Effective C# 原则1:尽可能的使用属性(property),而不是数据成员(field)
- WPF中,如何使用图像API进行绘制而不是XAML?——出自《IT168》
- 为什么你应该使用OpenGL而不是DirectX?
- 为什么你应该使用OPENGL而不是DIRECTX?
- 为什么delegate在声明属性的时候要使用assign?
- 为什么在判断中使用 "值 == 变量" 而不是 "变量 == 值"
- WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?