Qual è la differenza tra ContentControl e ContentPresenter?


208

Non sono sicuro di quando dovrei usare ContentPresenterinvece di ContentControl(e viceversa). Al momento, sto usando ContentControlpraticamente tutto il tempo nei miei messaggi DataTemplate. Quando sarebbe ContentPresenteruna scelta migliore? e perché?

Risposte:


164

ContentControlè una classe di base per i controlli che contengono altri elementi e hanno una Contentproprietà (ad esempio Button).

ContentPresenter viene utilizzato all'interno dei modelli di controllo per visualizzare il contenuto.

ContentControl, se usato direttamente (dovrebbe essere usato come classe di base), ha un modello di controllo che utilizza ContentPresenter per visualizzare il suo contenuto.

Le mie regole pratiche (non applicabile in tutti i casi, usa il tuo giudizio):

  1. ControlTemplateUso internoContentPresenter
  2. Al di fuori di ControlTemplate( DataTemplatemodelli inclusi e esterni) cerca di non utilizzare nessuno di essi, se necessario, devi preferireContentPresenter
  3. Sottoclasse ContentControlse si sta creando un controllo "lookless" personalizzato che ospita il contenuto e non è possibile ottenere lo stesso risultato modificando il modello di un controllo esistente (che dovrebbe essere estremamente raro).

1
Ciò significa che, in generale, dovrei probabilmente utilizzare ContentPresenter all'interno dei miei modelli di dati, perché è più leggero (ma funzionalmente equivalente se utilizzato in un DataTemplate come questo)? Quindi utilizzare ContentControl come classe di base se sto scrivendo un nuovo controllo?
Wilka

Ho modificato la risposta con maggiori dettagli quando avrei usato ContentPresenter e quando ContentControl
Nir

1
Ok ho idea che ContentPresenter dovrebbe essere usato nei template invece che in ContentControl, ma perché?
sabato

32
@sll - ContentControl è la classe base per ogni controllo che mostra "contenuto" (esempio: Etichetta), ContentPresenter è il codice utilizzato internamente da ContentControl per visualizzare il contenuto, quindi: 1. ContentPresenter è più leggero, 2. ContentPresenter è progettato per essere utilizzato all'interno dei modelli di controllo e 3. ContnetPresenter è progettato per essere utilizzato così com'è mentre ContentControl è progettato per essere esteso (ereditato da)
Nir

23
ContentPresenter si comporta diversamente da ContentControl quando si tratta di impostare la proprietà Content. Quando si imposta la proprietà Content di ContentPresenter, il suo DataContext cambia in modo che corrisponda alla proprietà Content, ma DataContext di ContentControl rimane inalterato. Ciò è importante se si dispone di altre proprietà su ContentPresenter impostate tramite associazione, poiché una volta modificato DataContext, tutti i collegamenti la utilizzano come origine.
user195275,

25

ContentPresenter viene solitamente utilizzato in un ControlTemplate, come segnaposto per dire "inserisci qui il contenuto effettivo".

Un ContentControl può essere utilizzato ovunque, non necessariamente in un modello. Raccoglierà qualsiasi DataTemplate definito per il tipo di contenuto assegnato


6
Un ContentPresenter non causerebbe l'applicazione di un DataTemplate al suo contenuto? Non è uno dei suoi scopi principali?
Drew Noakes,

1
mmm ... sì, probabilmente. Comunque, la spiegazione di Bea Stollnitz è molto meglio della mia;)
Thomas Levesque il

La tua risposta sintetica sembrava riassumerla rapidamente: credo che l'intero progetto di ContentPresenter sia semplicemente "implementare" l'inflazione di DataTemplate --- sembra avere il solo compito di individuare e gonfiare il modello, impostando anche DataContext; e provando quindi a "scomparire" il più possibile (PENSANDO che ANCORA tu possa legare all'interno del modello gonfiato a proprietà ambientali come le proprietà TextElement, provenienti quindi da ContentPresenter). Non devi preoccuparti di altre cose e gonfia il modello in un modo relativamente sottile. (Sto cercando il più sottile!)
Steven Coco,

9

Di recente ho scritto un post sul mio blog riguardante questi due controlli:

ContentPresenter vs ContentControl (EDIT: collegamento interrotto sostituito con versione archiviata.)

Il ContentPresenter.ContentSource è ciò che rende in realtà la più grande differenza tra le due classi. La proprietà ContentSource ha senso solo all'interno di ControlTemplate; determina con quale proprietà TemplatedParent deve essere mappato il contenuto. Ad esempio, se un controllo contiene una proprietà di dipendenza MyProperty1, allora potremmo trovare quanto segue al suo interno ControlTemplate:

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

Il contenuto di ContentPresenter riceverà il valore di MyProperty1.

Si noti che se il nome della proprietà è Content, non è necessario specificare ContentSourcepoiché è il valore predefinito.

Per coloro che conoscono angularJs: questo è simile al transclude mecanismo.


2

È una vecchia domanda ma stavo solo finendo di sviluppare un Tile Control animato, modello basato su un'app universale, guarda questo codice dal vecchio SDK WP7 / 8 del telefono:

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

Qui puoi vedere ContentControl è il Contenitore e il Presenter per la visualizzazione del contenuto. Nella maggior parte dei casi, ControlTemplate sarà il contenitore, ma se si desidera in un ControlTemplatealtro contenitore è possibile inserire un contenitore aggiuntivo: ContentControlin esso e per presentare il contenuto separatamente ContentPresenter. Se non hai bisogno di un contenitore separato, usa semplicemente ControlTemplateeControlPresentersper la visualizzazione di blocchi di contenuto, almeno è quello che hanno fatto i ragazzi di Microsoft quando hanno sviluppato l'SDK WP7 / 8. ContentControl può anche essere utilizzato per visualizzare il contenuto, ma serve sia come contenitore che come presentatore. Quindi nel codice di esempio sopra il suo scopo è suddiviso in Contenitore e Presentatore. In esempi dinamici è possibile visualizzare il contenitore (può avere uno sfondo vuoto o qualcosa che non è ancora presente) e quindi riempirlo dinamicamente con il contenuto del presentatore. Un contenitore ha dimensioni (larghezza, altezza ecc.), Metti quelle proprietà sul controllo contenitore e presenti il ​​contenuto su di esso. Nell'esempio ContentControl determina cosa deve essere fatto con il contenuto del presentatore.


1

A volte un esempio è più semplice del gergo teorico. In un sito Web MS (scorrere verso il basso: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx ), utilizza un pulsante come un esempio. Un pulsante ha un ContentControl, che consente di posizionare un controllo o un controllo personalizzato che potrebbe essere un'immagine, testo, checkBox, StackPanel, griglia, qualunque cosa.

Dopo la personalizzazione di Button, ora su Xaml, puoi scrivere

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

Nel codice di esempio sopra, "my: Button.Content" è ContentControl. AnotherControl sarà collocato in base a quanto specificato in ContentPresenter.

Allo stesso modo, quando confronta TextBox e TextBlock, TextBox ha un ContentPresenter per farci roba in esso proprio come nell'esempio Button sopra mentre un TextBlock no. Un blocco di testo consente solo di inserire il testo.


2
A Buttonnon ha un [ ContentControl] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), è un (eredita da) ContentControl. L' Button ha un ContentPresenter. Nota che puoi farlo con lo standard Button, non è necessario personalizzarlo.
OR Mapper,

Ma non correlato a questo, questa risposta non spiega se e perché, al posto di ContentPresenter, a ContentControlnon possa essere usato altrettanto bene nella ControlTemplatevisualizzazione del contenuto di Button. Come tale, non risponde alla domanda.
OR Mapper,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.