2013-01-24 22 views
10

Bir StackPanel çocukları belirli türden kontroller stil gerekWPF ControlTemplate stile

çalışır şeyler kırar. Kullanıyorum:

<StackPanel> 
    <StackPanel.Resources> 
     <Style TargetType="{x:Type TextBlock}">...</Style> 
    </StackPanel.Resources> 
    <TextBlock ...> 
    ... 
</StackPanel> 

Ve bu iyi çalışıyor! Her bir TextBlock, stilin nasıl çizileceğini öğrenmek için ebeveyninin (StackPanel) kaynaklarına bakar. TextBlock'u bir StackPanel'den aşağıya doğru yuvarlamanızın önemi yoktur ... eğer doğrudan ebeveyninde bir stil bulamazsa, ebeveynin ebeveyine bakar ve bir şey bulana kadar (bu durumda) , tanımlanan stil).

Bir Şablon vardı ContentControl, içeride bir TextBlock iç içe zaman bir sorunla karşılaştık

çalışmıyor şeyler (aşağıdaki kodu bakınız). ControlTemplate, bir TextBlock'un stilini ebeveynlerinden, büyükanne ve büyükbabalarından alma şeklini bozuyor gibi görünüyor ...

Bir ControlTemplate'in kullanımı, TextBlock'un haklı stilini (StackPanel'deki) bulma araçlarını etkin bir şekilde ortadan kaldırıyor gibi görünüyor. Kaynaklar). Bir ControlTemplate ile karşılaştığında, ağacın içindeki kaynaklarda stilini aramayı durdurur ve bunun yerine Uygulamanın kendisinin Birleştirilmiş Sözlüğünde varsayılan stili kullanır.

<StackPanel Orientation="Vertical" Background="LightGray"> 
    <StackPanel.Resources> 
     <Style TargetType="{x:Type TextBlock}"> 
      <Setter Property="Foreground" Value="Green" /> 
     </Style> 
    </StackPanel.Resources> 

    <TextBlock Text="plain and simple in stackpanel, green" /> 
    <ContentControl> 
     <TextBlock Text="inside ContentControl, still green" /> 
    </ContentControl> 
    <ContentControl> 
     <ContentControl.Template> 
      <ControlTemplate TargetType="{x:Type ContentControl}"> 
       <StackPanel Orientation="Vertical"> 
        <ContentPresenter /> 
        <TextBlock Text="how come this one - placed in the template - is not green?" /> 
       </StackPanel> 
      </ControlTemplate> 
     </ContentControl.Template> 
     <TextBlock Text="inside ContentControl with a template, this one is green as well" /> 
    </ContentControl> 

</StackPanel> 

bir yolu var mı - o ControlTemplate içindeki TextBlock tanımlı tarzı bulmak yapmak - ControlTemplate.Resources için StackPanel.Resources in Style çoğaltarak başka mı? WPF bir bir sınır olması ControlTemplates dikkate alır ve şablonların içine (bir x:Key olmadan stilleri) örtük stilleri geçerli olmayacaktır

cevap

21

teşekkürler ....

Ancak bu kuralın bir istisnası vardır: Control'dan gelen her şey örtülü stiller uygular.

Yani onun yerine bir TextBlock bir Label kullanabilir ve bunun FrameworkElement yerine Control den Ancak bu yana TextBlock devralır XAML hiyerarşi daha yukarı tanımlanan örtük stilini de geçerli olacak, otomatik olarak örtülü stili uygulamak ve alışkanlık elle eklemek zorunda.

Bunu aşmanın Benim en yaygın yolu, mevcut örtülü TextBlock stile bu kurtulmanın bir

<ControlTemplate.Resources> 
     <Style TargetType="{x:Type TextBlock}" 
       BasedOn="{StaticResource {x:Type TextBlock}}" /> 
    <ControlTemplate.Resources> 

Diğer yaygın yolları BasedOn olduğunu ControlTemplate.Resources bir örtük tarz eklemektir şunlardır:

  • Kapalı stili <Application.Resources>'a yerleştirin. Buraya yerleştirilen stiller, şablon sınırlarından bağımsız olarak, tüm uygulamanız için geçerli olacaktır.o Düğmeler veya Comboboxes

    <Application.Resources> 
        <Style TargetType="{x:Type TextBlock}"> 
         <Setter Property="Foreground" Value="Green" /> 
        </Style> 
    </Application.Resources> 
    
  • Kullanım bunun yerine Control miras beri bir TextBlock bir Label gibi, hem de diğer kontrollerin iç TextBlocks stil uygular gibi olsa Buna dikkat et, bu nedenle örtülü geçerli olacaktır ControlTemplate

  • dışında tanımlanan stiller taban tarzı bir x:Key ver ve ControlTemplate içinde bir örtülü TextBlock stilleri için taban tarzı olarak kullanın. Ancak bir x:Key niteliğini

    <Style x:Key="BaseTextBlockStyle" TargetType="{x:Type TextBlock}"> 
        <Setter Property="Foreground" Value="Green" /> 
    </Style> 
    
    ... 
    
    <ControlTemplate.Resources> 
        <Style TargetType="{x:Type TextBlock}" 
         BasedOn="{StaticResource BaseTextBlockStyle}" /> 
    <ControlTemplate.Resources> 
    
+0

Büyük açıklama var taban stilleri için kullanılıyor, hemen hemen üst çözüm olarak aynısı! Ayrıca BasedOn = "{StaticResource {x: Type TextBlock}}" kullanım şeklini de beğeniyorum. İlginç. Ve şimdi WPF'nin ControlTemplates'ı bir sınır olarak gördüğünü biliyorum, etrafta çalışmayı deneyebilirim :) –

+0

Teşekkürler, nihayet bir Stili ControlTemplate'ime nasıl uygulayacağımı anladım. Üçüncü örnek aydınlatıcıydı ve bana sadece ihtiyacım olan ControlTemplate (ler) 'e bir stil uygulamamı sağlıyor. –