我不确定何时应该使用ContentPresenter
代替ContentControl
(反之亦然)。目前,我在ContentControl
中几乎一直使用DataTemplate
。什么时候ContentPresenter
会是更好的选择?为什么?
答案 0 :(得分:153)
ContentControl
是包含其他元素且具有Content
- 属性的控件的基类(例如,Button
)。
ContentPresenter
来显示内容。
ContentControl
,当直接使用时(它应该用作基类),有一个控件模板,它使用ContentPresenter来显示它的内容。
我的经验法则(不适用于所有情况,请使用您的判断):
ControlTemplate
内使用ContentPresenter
ControlTemplate
之外(包括DataTemplate
和外部模板)尽量不要使用其中任何一个,如果需要,您必须更喜欢ContentPresenter
ContentControl
如果您要创建一个托管内容的自定义“无外观”控件,并且您无法通过更改现有控件的模板获得相同的结果(这应该非常罕见)。答案 1 :(得分:24)
ContentPresenter通常用在ControlTemplate中,作为占位符来说“将实际内容放在这里”。
ContentControl可以在任何地方使用,不一定在模板中。它将获取为分配给它的内容类型定义的任何DataTemplate
答案 2 :(得分:8)
我最近在博客上写了一篇关于这两个控件的帖子:
ContentPresenter vs ContentControl(编辑:已删除的链接已替换为存档版本。)
ContentPresenter.ContentSource 实际上是两个类之间最大的区别。
ContentSource属性仅在ControlTemplate中有意义;它确定内容应映射到哪个TemplatedParent属性。
例如,如果控件包含依赖项属性MyProperty1
,那么我们可能会在其ControlTemplate
中找到以下内容:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
ContentPresenter的内容将获得MyProperty1
的价值。
请注意,如果属性的名称为Content
,则无需指定ContentSource
,因为它是默认值。
对于那些了解angularJs的人:这类似于transclude mecanism。
答案 3 :(得分:1)
有时候一个例子比理论术语更容易。在MS网站(滚动到底部:http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx)中,它使用一个按钮作为示例。 Button有一个ContentControl,它允许你放置一个控件或一个自定义控件,可以是Image,Text,CheckBox,StackPanel,Grid等等。
自定义Button后,现在在Xaml上,你可以写
<my:Button>
<my:Button.Content>
<my:AnotherControl>
</my:Button.Content>
</my:Button>
在上面的示例代码中,“my:Button.Content”是ContentControl。 AnotherControl将放置在ContentPresenter所指定的位置。
类似地,当比较TextBox和TextBlock时,TextBox有一个ContentPresenter,您可以像上面的Button示例一样填充其中的内容,而TextBlock则不会。 TextBlock仅允许您输入文本。
答案 4 :(得分:0)
这是一个老问题,但我刚刚完成开发动画平铺控件,基于通用应用程序的模板,请查看旧手机WP7 / 8 SDK中的代码:
<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
<ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>
在这里,您可以看到ContentControl是用于显示内容的Container和Presenter。在大多数情况下,ControlTemplate将是Container,但如果您想在ControlTemplate
另一个容器中,可以在其中放置一个额外的容器:ContentControl
,并为内容单独显示ContentPresenter
。如果您不需要单独的容器,那么只需使用ControlTemplate
和ControlPresenters
来显示内容块,至少是微软开发WP7 / 8 SDK时的内容。 ContentControl也可以用于显示内容,但它同时用作容器和演示者。因此,在上面的示例代码中,其目的是在Container和Presenter中拆分。在动态样本中,您可以显示容器(它可以具有空白背景或尚未存在的空白背景),然后使用演示者内容动态填充它。容器具有尺寸(宽度,高度等),您将这些属性放在容器控件上并在其上显示内容。在示例中,ContentControl确定要对演示者内容执行的操作。