ContentControl和ContentPresenter有什么区别?

时间:2009-08-17 13:34:06

标签: .net wpf contentcontrol contentpresenter

我不确定何时应该使用ContentPresenter代替ContentControl(反之亦然)。目前,我在ContentControl中几乎一直使用DataTemplate。什么时候ContentPresenter会是更好的选择?为什么?

5 个答案:

答案 0 :(得分:153)

ContentControl是包含其他元素且具有Content - 属性的控件的基类(例如,Button)。

控件模板中使用

ContentPresenter来显示内容。

ContentControl,当直接使用时(它应该用作基类),有一个控件模板,它使用ContentPresenter来显示它的内容。

我的经验法则(不适用于所有情况,请使用您的判断):

  1. ControlTemplate内使用ContentPresenter
  2. ControlTemplate之外(包括DataTemplate和外部模板)尽量不要使用其中任何一个,如果需要,您必须更喜欢ContentPresenter
  3. 子类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。如果您不需要单独的容器,那么只需使用ControlTemplateControlPresenters来显示内容块,至少是微软开发WP7 / 8 SDK时的内容。 ContentControl也可以用于显示内容,但它同时用作容器和演示者。因此,在上面的示例代码中,其目的是在Container和Presenter中拆分。在动态样本中,您可以显示容器(它可以具有空白背景或尚未存在的空白背景),然后使用演示者内容动态填充它。容器具有尺寸(宽度,高度等),您将这些属性放在容器控件上并在其上显示内容。在示例中,ContentControl确定要对演示者内容执行的操作。