ContentControl和ContentPresenter有什么区别?

Wil*_*lka 200 .net wpf contentpresenter contentcontrol

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

Nir*_*Nir 157

ContentControl是包含其他元素并具有Content-property(例如Button)的控件的基类.

ContentPresenter 用于控件模板内部以显示内容.

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

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

  1. 内部ControlTemplate使用ContentPresenter
  2. ControlTemplate(包括DataTemplate和模板外)尝试不使用它们中的任何一个,如果需要,你必须更喜欢ContentPresenter
  3. ContentControl如果要创建一个托管内容的自定义"无视"控件,则子类,并且通过更改现有控件的模板无法获得相同的结果(这应该非常罕见).

  • @sll - ContentControl是显示"内容"的每个控件的基类(例如:Label),ContentPresenter是ContentControl内部用于显示内容的代码 - 因此:1.ContentPresenter更轻量级,2.ContentPresenter设计为在控件模板和内部使用3. ContnetPresenter设计为按原样使用,而ContentControl设计为扩展(继承自) (31认同)
  • 在设置Content属性时,ContentPresenter的行为与ContentControl不同.设置ContentPresenter的Content属性时,其DataContext将更改为与Content属性匹配,但ContentControl的DataContext不受影响.如果您通过绑定在ContentPresenter上设置了其他属性,则这很重要,因为一旦DataContext更改,所有绑定都将其用作源. (22认同)
  • 好吧,我知道应该在模板中使用 ContentPresenter 而不是 ContentControl,但为什么呢? (2认同)

Tho*_*que 24

ContentPresenter通常用在ControlTemplate中,作为占位符来说"将实际内容放在这里".

ContentControl可以在任何地方使用,不一定在模板中.它将获取为分配给它的内容类型定义的任何DataTemplate

  • ContentPresenter不会导致DataTemplate应用于它的内容吗?这不是它的主要目的之一吗? (6认同)
  • 您简洁的回答似乎很快就总结了这一点:我相信 ContentPresenter 的整个设计就是简单地“实现”DataTemplate 膨胀 --- 它似乎唯一的工作就是定位和膨胀模板,也设置 DataContext ;然后尝试尽可能地“消失”(尽管您仍然可以在膨胀的模板中绑定到环境属性,例如来自 ContentPresenter 的 TextElement 属性)。你不需要担心其他事情,它只是以相对苗条的方式膨胀模板。(我正在寻找最苗条的!) (2认同)

Cha*_*IER 8

我最近在我的博客上写了一篇关于这两个控件的帖子:

ContentPresenter与ContentControl(编辑:已删除链接替换为存档版本.)

ContentPresenter.ContentSource就是实际上使得两个类之间的最大区别.ContentSource属性仅在ControlTemplate中有意义; 它确定内容应映射到哪个TemplatedParent属性.例如,如果控件包含依赖项属性MyProperty1,那么我们可能会在其中找到以下内容ControlTemplate:

<ControlTemplate TargetType="MyControl" >
    [...]
       <ContentPresenter ContentSource="MyProperty1" />
    [...]
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

ContentPresenter的内容将获得值MyProperty1.

请注意,如果属性的名称是Content,则无需指定,ContentSource因为它是默认值.

对于那些了解angularJs的人:这类似于transclude mecanism.