ContentControl ve ContentPresenter arasındaki fark nedir?


208

Ben kullanmalıyım zaman emin değilim ContentPresenteryerine ContentControl(ve tersi). Şu anda, ContentControlneredeyse her zaman kullanıyorum DataTemplate. Ne zaman ContentPresenterdaha iyi bir seçim olur? ve neden?

Yanıtlar:


164

ContentControl, diğer öğeleri içeren ve Content-property (örneğin Button) içeren denetimler için bir temel sınıftır .

ContentPresenter içeriği görüntülemek için kontrol şablonlarının içinde kullanılır.

ContentControl, doğrudan kullanıldığında (temel sınıf olarak kullanılması gerekiyor), içeriğini görüntülemek için ContentPresenter kullanan bir kontrol şablonuna sahiptir.

Temel kurallarım (her durumda geçerli değildir, kararınızı kullanın):

  1. İç ControlTemplatekullanımContentPresenter
  2. Dışında ControlTemplate( DataTemplateşablonlar dahil ve hariç) bunlardan herhangi birini kullanmamaya çalışın, ihtiyacınız varsa, tercih etmelisinizContentPresenter
  3. ContentControlİçeriği barındıran özel bir "görünmez" denetim oluşturuyorsanız ve mevcut bir denetimin şablonunu değiştirerek aynı sonucu elde edemezseniz (çok nadir olması gerekir) alt sınıf .

1
Bu, genel olarak, DataTemplates'imin içinde muhtemelen ContentPresenter kullanmam gerektiği anlamına mı geliyor, çünkü daha hafif (ancak böyle bir DataTemplate'te kullanıldığında işlevsel olarak eşdeğer)? Eğer yeni bir kontrol yazıyorum sonra sadece temel sınıf olarak ContentControl kullanın?
Wilka

ContentPresenter'ı ne zaman kullanacağım ve ContentControl
Nir

1
Tamam ContentPresenter'ın ContentControl yerine şablonlarda kullanılması gerektiği konusunda fikrim var, ama neden?
sll

32
@sll - ContentControl "içerik" görüntüleyen her kontrol için temel sınıftır (örnek: Etiket), ContentPresenter içeriği görüntülemek için ContentControl tarafından dahili olarak kullanılan koddur - yani: 1. ContentPresenter daha hafiftir, 2. ContentPresenter ContnetPresenter olduğu gibi kullanılmak üzere tasarlanmıştır, ContentControl ise genişletilecek (devralınan) olarak tasarlanmıştır
Nir

23
Content özelliği ayarlandığında, ContentPresenter, ContentControl'den farklı davranır. ContentPresenter'ın Content özelliğini ayarladığınızda, DataContext öğesi Content özelliğiyle eşleşecek şekilde değişir, ancak ContentControl'ün DataContext'i bundan etkilenmez. DataContext değiştiğinde, tüm bağlamalar bunu kaynak olarak kullandığından ContentPresenter'da bağlama yoluyla ayarlanmış başka özellikleriniz varsa bu önemlidir.
user195275

25

ContentPresenter genellikle bir ControlTemplate içinde "gerçek içeriği buraya koy" demek için bir yer tutucu olarak kullanılır.

Bir ContentControl, bir şablonda değil, her yerde kullanılabilir. Kendisine atanan içerik türü için tanımlanan herhangi bir DataTemplate'i alır


6
Bir ContentPresenter, içeriğine bir DataTemplate uygulanmasına neden olmaz mı? Bu birincil amaçlarından biri değil mi?
Drew Noakes

1
mmm ... evet, muhtemelen. Her neyse, Bea Stollnitz'in açıklaması benimkinden çok daha iyi;)
Thomas Levesque

Kısa ve özlü cevabınız hızlı bir şekilde özetliyor gibiydi: ContentPresenter'ın tüm tasarımının sadece DataTemplate enflasyonunu "uygulamak" olduğuna inanıyorum --- sadece şablonu bulmak ve şişirmek, DataContext'i ayarlamak gibi tek bir iş var gibi görünüyor; ve daha sonra mümkün olduğunca "kaybolmaya" çalışarak (STILL, şişirilmiş şablon içinde TextElement özellikleri gibi ortam özelliklerine, daha sonra ContentPresenter'dan gelebilir). Başka şeyler için endişelenmenize gerek yok ve sadece şablonu nispeten ince bir şekilde şişiriyor. (En ince olanı arıyorum!)
Steven Coco

9

Kısa bir süre önce blogumda şu iki kontrolle ilgili bir yazı yazdım:

ContentPresenter ve ContentControl (EDIT: Bozuk bağlantı, arşivlenmiş sürümle değiştirildi.)

ContentPresenter.ContentSource aslında iki sınıf arasındaki en büyük fark yaratır şeydir. ContentSource özelliği yalnızca bir ControlTemplate içinde anlamlıdır; içeriğin hangi TemplatedParent özelliğiyle eşlenmesi gerektiğini belirler. Örneğin, bir denetim bir bağımlılık özelliği içeriyorsa MyProperty1, bunun içinde aşağıdakileri bulabiliriz ControlTemplate:

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

ContentPresenter içeriği değerini alır MyProperty1.

Mülkün adı varsa , varsayılan değer olarak Contentbelirtmeye gerek olmadığını lütfen unutmayın ContentSource.

AçısalJ'leri bilenler için: bu, mekanizmi aşmaya benzer.


2

Bu eski bir soru ama ben sadece evrensel bir uygulama için dayalı bir animasyonlu Çini Kontrol, şablon geliştirme bitirme, eski Telefon WP7 / 8 SDK bu koda bakmak:

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

Burada ContentControl'ün içeriği görüntülemek için Kapsayıcı ve Sunum Yaptığını görebilirsiniz. Çoğu durumda ControlTemplate Kapsayıcı olacaktır, ancak ControlTemplatebaşka bir kapsayıcısında isterseniz, içine ContentControlve içeriği ayrı bir şekilde sunmak için fazladan bir Kap koyabilirsiniz ContentPresenter. Eğer ayrı bir kap ihtiyacım yok o zaman sadece kullanmak ControlTemplateveControlPresentersiçerik bloklarını görüntülemek için, en azından Microsoft'taki çocuklar WP7 / 8 SDK'yı geliştirdiklerinde yaptıkları şey. ContentControl, içeriği görüntülemek için de kullanılabilir, ancak daha sonra hem kapsayıcı hem de sunum yapan kişi olarak hizmet eder. Bu yüzden yukarıdaki örnek kodda amacı Container ve Presenter'da bölünür. Dinamik örneklerde kapsayıcıyı görüntüleyebilir (boş bir arka planı veya henüz orada olmayan bir şey olabilir) ve ardından dinamik olarak sunum yapan kişi içeriği ile doldurabilirsiniz. Bir kabın boyutları (genişlik, yükseklik vb.) Vardır, bu özellikleri kap denetimine koyar ve üzerinde içerik sunarsınız. Örnekte ContentControl, sunucu içeriğiyle ne yapılması gerektiğini belirler.


1

Bazen bir örnek teorik jargondan daha kolaydır. Bir MS web sitesinde (Aşağıya kaydırın: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx ), Bir örnek. Bir Düğme, bir denetim veya bir Resim, Metin, CheckBox, StackPanel, Grid gibi herhangi bir özel denetim yerleştirmenize izin veren bir ContentControl'e sahiptir.

Düğmenin özelleştirilmesinden sonra, şimdi Xaml'de,

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

Yukarıdaki örnek kodda, "my: Button.Content" ContentControl olduğunu. AnotherControl, ContentPresenter'ın belirttiği yere yerleştirilecektir.

Benzer şekilde, TextBox ve TextBlock'u karşılaştırdığınızda, TextBox, yukarıdaki Button örneğinde olduğu gibi bir şey doldurmanız için bir ContentPresenter'a sahipken, TextBlock bunu yapmaz. Bir TextBlock yalnızca metin girmenize izin verir.


2
Bir Buttonetmez sahip bir [ ContentControl] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), bu a, (devralır) ContentControl. Button Vardır bir ContentPresenter. Bunu standartla yapabileceğinizi, Buttonözelleştirmenize gerek olmadığını unutmayın.
VEYA Haritacı

Ama bu kesinlikle hiçbir ilgisi olmayan bu cevap yerine olsun ve neden açıklamıyor ContentPresenter, bir ContentControlde sadece de kullanılamadı ControlTemplateiçeriğini görüntülemek için Button. Bu nedenle, soruya cevap vermez.
VEYA Haritacı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.