Quelle est la différence entre ContentControl et ContentPresenter?

Je ne sais pas quand je devrais utiliser ContentPresenter au lieu de ContentControl (et vice-versa). En ce moment, j'utilise ContentControl à peu près tout le temps dans Mes DataTemplate . Quand ContentPresenter serait-il un meilleur choix? et pourquoi?

189
demandé sur barik 2009-08-17 17:34:06

5 réponses

ContentControl est une catégorie de base pour les commandes qui contiennent d'autres éléments et qui ont une propriété Content (par exemple, Button ).

ContentPresenter est utilisé à l'intérieur des gabarits de contrôle pour afficher le contenu.

ContentControl , lorsqu'il est utilisé directement (il est censé être utilisé comme une classe de base), a un modèle de contrôle qui utilise ContentPresenter pour afficher son contenu.

mes règles de base (non applicable en chaque cas, utilisez votre jugement):

  1. à l'Intérieur ControlTemplate utiliser ContentPresenter
  2. en dehors de ControlTemplate (y compris DataTemplate et à l'extérieur des gabarits) essayez de ne pas utiliser l'un d'eux, si vous avez besoin, vous devez préférer ContentPresenter
  3. sous-classe ContentControl si vous créez un contrôle personnalisé "sans regard" que le contenu de l'hôte et vous ne pouvez pas obtenir le même résultat en changeant le modèle d'un contrôle existant (qui devrait être extrêmement rare).
151
répondu Nir 2018-04-09 15:11:58

ContentPresenter est habituellement utilisé dans un ControlTemplate, comme un espace réservé pour dire "mettre le contenu réel ici".

un ContentControl peut être utilisé n'importe où, pas nécessairement dans un modèle. Il récupérera tout attribut de données défini pour le type de contenu qui lui est assigné

21
répondu Thomas Levesque 2009-08-17 13:37:15

j'ai récemment écrit un billet sur mon blog concernant ces deux contrôles:

ContentPresenter vs ContentControl (EDIT: lien Cassé remplacé par une version archivée.)

Le ContentPresenter.ContentSource est ce qui fait la plus grande différence entre les deux classes. La propriété ContentSource n'a de sens que dans un ControlTemplate; elle détermine quelle propriété TemplatedParent le contenu doit être cartographié. Par exemple, si un contrôle contient une propriété de dépendance MyProperty1 , alors nous pourrions trouver ce qui suit dans sa ControlTemplate :

<ControlTemplate TargetType="MyControl" >
    [...]
       <ContentPresenter ContentSource="MyProperty1" />
    [...]
</ControlTemplate>

le contenu du ContentPresenter recevra la valeur de MyProperty1 .

Veuillez noter que si le nom de la propriété est Content , il n'est pas nécessaire de préciser ContentSource , comme c'est la valeur par défaut.

pour ceux qui connaissent angularJs: ceci est similaire au mecanisme transclude.

8
répondu Charles HETIER 2017-10-25 23:52:47

parfois, un exemple est plus facile que le jargon théorique. Dans un site MS web (Faites défiler vers le bas: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter (v=V110).aspx ), il utilise un bouton comme exemple. Un bouton a un ContentControl, qui vous permet de placer un contrôle ou un contrôle personnalisé qui pourrait être une Image, un texte, une case à cocher, un empattement, une grille, n'importe quoi.

après la personnalisation du bouton, maintenant sur le Xaml, tu peux écrire

<my:Button>
   <my:Button.Content>
      <my:AnotherControl>
   </my:Button.Content>
</my:Button>

dans l'exemple de code ci-dessus, le bouton" my:".Content " est le ContentControl. L'AnotherControl sera placé à ce que vous aviez spécifié où le ContentPresenter est.

de la même façon, quand on compare TextBox et Textlock, TextBox a un ContentPresenter pour vous pour y mettre des trucs comme le bouton ci-dessus, alors qu'un Textlock ne le fait pas. Un cadenas textuel ne vous permet d'entrer que du texte.

0
répondu Wayne Lo 2014-01-23 20:15:01

C'est une vieille question mais je finissais juste de développer un contrôle de tuile animé, modèle basé sur une application universelle, regardez ce code de l'ancien téléphone WP7 / 8 SDK:

<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
    <ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>

ici vous pouvez voir le ContentControl est le conteneur et le présentateur pour afficher le contenu. Dans la plupart des cas le ControlTemplate sera le Container mais si vous voulez dans votre ControlTemplate un autre container vous pouvez mettre un Container supplémentaire: ContentControl et pour présentant le contenu d'un ContentPresenter séparé . Si vous n'avez pas besoin d'un conteneur séparé, alors il suffit d'utiliser ControlTemplate et ControlPresenters pour afficher des blocs de contenu au moins ce que les gars de Microsoft ont fait quand ils ont développé le SDK WP7/8. Le ContentControl peut également être utilisé pour afficher du contenu, mais il sert à la fois de conteneur et de présentateur. Ainsi, dans le code échantillon ci-dessus son but est divisé en conteneur et présentateur. Dans les échantillons dynamiques, vous pouvez afficher le conteneur (il peut avoir un fond vide ou quelque chose qui n'est pas encore là) et ensuite le remplir dynamiquement avec le contenu du présentateur. Un conteneur a des dimensions (largeur,hauteur, etc.), vous mettez ces propriétés sur le conteneur de contrôle et de présenter le contenu. Dans l'échantillon, le ContentControl détermine ce qui doit être fait avec le contenu du présentateur.

0
répondu Herman Van Der Blom 2014-04-25 21:49:43