我不确定何时应该使用ContentPresenter
而不是ContentControl
(反之亦然)。目前,我ContentControl
几乎一直在使用我DataTemplate
的 s. 什么时候会ContentPresenter
是更好的选择?为什么?
5 回答
ContentControl
是包含其他元素并具有Content
- 属性(例如Button
)的控件的基类。
ContentPresenter
在控件模板中用于显示内容。
ContentControl
,当直接使用时(它应该用作基类),有一个控件模板,它使用 ContentPresenter 来显示它的内容。
我的经验法则(并非在所有情况下都适用,请自行判断):
- 内部
ControlTemplate
使用ContentPresenter
- 外部
ControlTemplate
(包括DataTemplate
和外部模板)尽量不要使用它们中的任何一个,如果需要,您必须首选ContentPresenter
ContentControl
如果您正在创建一个托管内容的自定义“无外观”控件并且您无法通过更改现有控件的模板获得相同的结果(这应该非常罕见),则子类化。
ContentPresenter 通常用在 ControlTemplate 中,作为一个占位符来表示“将实际内容放在这里”。
ContentControl 可以在任何地方使用,不一定在模板中。它将获取为分配给它的内容类型定义的任何 DataTemplate
我最近在我的博客上写了一篇关于这两个控件的帖子:
ContentPresenter 与 ContentControl
ContentPresenter.ContentSource实际上是这两个类之间最大的区别。ContentSource 属性仅在 ControlTemplate 中才有意义;它确定内容应该映射到哪个 TemplatedParent 属性。例如,如果一个控件包含一个依赖属性MyProperty1
,那么我们可能会在它的内部找到以下内容ControlTemplate
:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
ContentPresenter 的内容将收到 的值MyProperty1
。
请注意,如果属性名称为Content
,则无需指定ContentSource
,因为它是默认值。
对于那些了解 angularJs 的人:这类似于 transclude mecanism。
这是一个老问题,但我刚刚完成了基于通用应用程序模板的动画平铺控件的开发,请查看旧电话 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
另一个容器中,您可以在其中放置一个额外的 Container:ContentControl
并将内容呈现为单独的ContentPresenter
. 如果您不需要单独的容器,则只需使用ControlTemplate
和ControlPresenters
用于显示内容块,至少这就是微软的人在开发 WP7/8 SDK 时所做的。ContentControl 也可用于显示内容,但它同时用作容器和演示者。所以在上面的示例代码中,它的用途被拆分为 Container 和 Presenter。在动态示例中,您可以显示容器(它可以有一个空背景或尚不存在的东西),然后用演示者内容动态填充它。容器具有尺寸(宽度、高度等),您将这些属性放在容器控件上并在其上显示内容。在示例中,ContentControl 确定必须对演示者内容执行的操作。
有时一个例子比理论术语更容易。在 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 只允许您输入文本。