2009-08-17 17 views

risposta

142

ContentControl è una classe di base per i controlli che contengono altri elementi e hanno un -property Content (per esempio, Button).

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

ContentControl, se utilizzato direttamente (deve essere utilizzato come classe base), dispone di un modello di controllo che utilizza ContentPresenter per visualizzarne il contenuto.

EDIT: Le mie regole di pollice (non applicabile in tutti i casi, usare il vostro giudizio):

  1. All'interno ControlTemplate uso ContentPresenter
  2. Al di fuori di ControlTemplate (compresi DataTemplate e modelli esterni) cercare di non utilizzare alcun di essi, se è necessario, è necessario preferire ContentPresenter
  3. Sottoclasse ContentControl se si crea un controllo "senza look" personalizzato del contenuto dell'host e non è possibile ottenere lo stesso risultato modificando il modello di un controllo esistente (che dovrebbe essere estremamente rari).
+1

Ciò significa che, in generale, dovrei probabilmente usare ContentPresenter nei miei DataTemplates, perché è più leggero (ma funzionalmente equivalente se usato in un DataTemplate come questo)? Quindi utilizzare ContentControl come classe base solo se sto scrivendo un nuovo controllo? – Wilka

+0

Ho modificato la risposta con maggiori dettagli quando userei ContentPresenter e quando ContentControl – Nir

+1

Ok ho idea che ContentPresenter debba essere usato nei template invece di ContentControl, ma perché? – sll

20

ContentPresenter viene in genere utilizzato in un oggetto ControlTemplate, come segnaposto per indicare "inserire il contenuto effettivo qui".

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

+6

Non un ContentPresenter potrebbe anche causare l'applicazione di un DataTemplate al suo contenuto? Non è questo uno dei suoi scopi principali? –

+1

mmm ... sì, probabilmente. Comunque, la spiegazione di Bea Stollnitz è molto migliore della mia) –

8

Recentemente ho scritto un post sul mio blog per quanto riguarda questi due controlli:

ContentPresenter vs ContentControl (EDIT:. Collegamento rotto sostituito con versione archiviata)

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

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

Il contenuto del ContentPresenter riceverà il valore di MyProperty1.

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

Per coloro che conoscono AngularJ: questo è simile al meccanismo di esclusione.

0

A volte un esempio è più semplice del gergo teorico. In un sito Web di MS (Scorri fino alla fine: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx), utilizza un pulsante come 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, qualsiasi cosa.

Dopo la personalizzazione di Button, ora sul Xaml, è possibile scrivere

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

Nel codice di esempio di cui sopra, la "mia: Button.Content" è la ContentControl. The AnotherControl sarà posto a ciò che hai specificato dove si trova ContentPresenter.

Analogamente, quando confronta TextBox e TextBlock, TextBox ha un ContentPresenter in cui puoi inserire elementi come nell'esempio sopra, mentre un TextBlock no. Un TextBlock ti consente solo di inserire del testo.

+1

Un ['Pulsante'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.button%28v=vs.110%29.aspx) non * ha * un [' ContentControl'] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), è * un * (ereditato da) 'ContentControl'. Il 'Button' * ha * un [' ContentPresenter'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter%28v=vs.110%29.aspx). Nota che puoi farlo con lo standard 'Button', non c'è bisogno di personalizzarlo. –

+0

Ma non correlato a questo, questa risposta non spiega se e perché, invece di 'ContentPresenter', un' ContentControl' non può essere usato altrettanto bene nel 'ControlTemplate' per visualizzare il contenuto del' Button'. In quanto tale, non risponde alla domanda. –

0

La sua una vecchia questione, ma ho appena finito di sviluppare un controllo delle mattonelle animate, modello basato per un'applicazione universale, guardare a questo codice dal vecchio telefono WP7/8 SDK:

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

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