我不确定什么时候应该使用ContentPresenter
而不是ContentControl
(反之亦然)。目前,我在我的DataTemplate
中几乎一直使用ContentControl
。什么情况下应该使用ContentPresenter
?为什么?
我不确定什么时候应该使用ContentPresenter
而不是ContentControl
(反之亦然)。目前,我在我的DataTemplate
中几乎一直使用ContentControl
。什么情况下应该使用ContentPresenter
?为什么?
ContentControl
是包含其他元素并具有 Content
属性的控件的基类,例如 Button
。
ContentPresenter
用于控件模板中显示内容。
当直接使用 ContentControl
(它应该被用作基类)时,它具有一个控件模板,使用 ContentPresenter 来显示其内容。
我的经验法则(并非适用于每种情况,请根据实际情况斟酌):
ControlTemplate
中使用 ContentPresenter
ControlTemplate
之外(包括 DataTemplate
和模板之外),尽量不要使用它们。如果需要,应优先选择 ContentPresenter
ContentControl
。ContentPresenter通常用于控件模板中,作为一个占位符,表示“在此放置实际内容”。
ContentControl可以在任何地方使用,不一定在模板中。它将获取为其分配的内容类型定义的任何DataTemplate。
我最近在博客上写了一篇关于这两个控件的帖子:
ContentPresenter vs ContentControl
ContentPresenter.ContentSource 是两个类之间最大的区别。
ContentSource 属性仅在 ControlTemplate 内有意义;它确定要将内容映射到哪个 TemplatedParent 属性。
例如,如果一个控件包含一个依赖属性 MyProperty1
,则我们可能在其 ControlTemplate
中找到以下内容:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
ContentPresenter的内容将接收MyProperty1的值。
请注意,如果属性名称为Content,则无需指定ContentSource,因为它是默认值。
对于了解angularJs的人:这类似于传递机制(transclude mecanism)。
这是一个老问题,但我刚刚完成了一个基于模板的通用应用程序动画瓷贴控件的开发。看看来自旧的Phone WP7/8 SDK的代码:
<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
<ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>
在这里,您可以看到ContentControl是用于显示内容的容器和呈现器。在大多数情况下,ControlTemplate将是容器,但如果您想在ControlTemplate
中使用另一个容器,则可以加入一个额外的容器:ContentControl
,以及用于呈现内容的一个单独的ContentPresenter
。如果您不需要单独的容器,则只需使用ControlTemplate
和ControlPresenter
来显示内容块,这至少是微软开发WP7/8 SDK时所做的。ContentControl也可用于显示内容,但此时它同时充当容器和呈现器。因此,在上面的示例代码中,它的目的被分为容器和呈现器。在动态示例中,您可以显示容器(它可以具有空背景或尚不存在的某些东西),然后动态填充它以呈现内容。容器具有尺寸(宽度、高度等),您可以在容器控件上放置这些属性,并在其上呈现内容。在示例中,ContentControl确定了如何处理呈现器内容。
ContentControl
是用于创建 WPF 自定义控件(不要与用户控件混淆)的类,因此它是您的顶级类。 ContentPresenter
就像任何其他“常规”控件一样。您可以在自定义或用户控件中使用它,在模板中使用它,或者仅在标记中使用它。
<my:Button>
<my:Button.Content>
<my:AnotherControl>
</my:Button.Content>
</my:Button>
Button
没有ContentControl
(内容控件),它是一个(继承自)ContentControl
。Button
有一个ContentPresenter
。请注意,您可以使用标准的Button
来实现这一点,无需自定义它。 - O. R. MapperContentPresenter
一样在ControlTemplate
中使用ContentControl
来显示Button
的内容,也没有解释为什么不能这样做。因此,它并没有回答问题。 - O. R. Mapper