2013-01-24 59 views
10

सामान है कि काम करता हैWPF ControlTemplate शैली टूट जाता है

मुझे लगता है कि एक StackPanel के बच्चे हैं एक खास प्रकार के नियंत्रण शैली की जरूरत है। मैं उपयोग कर रहा हूँ:

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

और यह ठीक काम करता है! प्रत्येक टेक्स्टब्लॉक यह पता लगाने के लिए कि यह कैसे स्टाइल किया जाना चाहिए, इसके माता-पिता (स्टैकपैनेल) के संसाधनों को देखता है। यह आप घोंसला TextBlock नीचे एक StackPanel नीचे ... अगर यह इसके प्रत्यक्ष माता पिता में एक शैली नहीं मिल रहा है, वह अपने माता पिता के माता पिता पर इतने पर देखने के लिए और होगा कितनी दूर, कोई फर्क नहीं पड़ता जब तक यह (कुछ पाता है इस मामले में , शैली जिसे परिभाषित किया गया था)।

सामान कि

मैं जब मैं एक ContentControl है, जो एक खाका था अंदर एक TextBlock नेस्ट कोई समस्या हुई थी काम नहीं करता है (नीचे दिए गए कोड को देखें)। कंट्रोल टेम्पलेट अपने पाठकों को अपने माता-पिता, दादा दादी से पुनर्प्राप्त करने के तरीके को बाधित करता प्रतीत होता है ...

कंट्रोल टेम्पलेट का उपयोग प्रभावी ढंग से टेक्स्टब्लॉक के सही तरीके को ढूंढने के साधनों को ठंडा कर देता है (स्टैकपैनल में से एक। संसाधन)। जब यह ControlTemplate से मुकाबला करता है, तो यह पेड़ के संसाधनों में अपनी शैली की तलाश करना बंद कर देता है, और इसके बजाय एप्लिकेशन के मर्ज किए गए शब्दकोश में शैली के लिए डिफ़ॉल्ट रूप से चूक जाता है।

<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> 

वहाँ एक रास्ता है - कि ControlTemplate अंदर TextBlock परिभाषित शैली प्राप्त करने के लिए - ControlTemplate.Resources को StackPanel.Resources में शैली डुप्लिकेट करने के अलावा?

धन्यवाद ...

उत्तर

21

WPF समझता है ControlTemplates एक सीमा है, और (एक x:Key बिना शैलियों) अंतर्निहित शैलियों लागू नहीं होगा टेम्पलेट्स के अंदर।

लेकिन इस नियम के लिए एक अपवाद है: Control से प्राप्त कुछ भी अंतर्निहित शैलियों को लागू करेगा।

तो तुम एक TextBlock के बजाय एक Label इस्तेमाल कर सकते हैं, और यह FrameworkElement बजाय Control से हालांकि बाद TextBlock इनहेरिट करती है, अंतर्निहित शैली अपने XAML पदानुक्रम आगे परिभाषित लागू होगा, यह अंतर्निहित शैली स्वचालित रूप से लागू नहीं होगा और आप इसे मैन्युअल रूप से जोड़ना होगा।

मेरे सबसे आम तरीका यह चारों ओर पाने के लिए ControlTemplate.Resources कि है BasedOn मौजूदा अंतर्निहित TextBlock शैली इस के आसपास होने का

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

अन्य आम तरीकों से एक अंतर्निहित शैली को जोड़ने के लिए है:

  • <Application.Resources> में अंतर्निहित शैली रखें। टेम्पलेट सीमाओं के बावजूद यहां रखे गए शैलियां आपके पूरे एप्लिकेशन पर लागू होंगी।हालांकि इस बात से सावधान रहें, के रूप में यह शैली TextBlocks को अन्य नियंत्रण के अंदर के रूप में अच्छी तरह से बटन या comboboxes

    <Application.Resources> 
        <Style TargetType="{x:Type TextBlock}"> 
         <Setter Property="Foreground" Value="Green" /> 
        </Style> 
    </Application.Resources> 
    
  • उपयोग एक TextBlock के बाद से यह Control से विरासत में मिला है के बजाय एक Label की तरह लागू होगा, है, तो अंतर्निहित लागू होगी ControlTemplate

  • बाहर परिभाषित शैलियाँ आधार शैली एक x:Key दो और ControlTemplate अंदर एक अंतर्निहित TextBlock शैलियों के लिए आधार शैली के रूप में उपयोग। यह बहुत ज्यादा शीर्ष समाधान के रूप में ही है, लेकिन यह है कि एक x:Key विशेषता

    <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

महान स्पष्टीकरण आधार शैलियों के लिए प्रयोग किया जाता है! मैं जिस तरह से आप आधारितऑन = "{स्टेटिक रिसोर्स {एक्स: टाइप टेक्स्टब्लॉक}} का उपयोग करने के तरीके को भी पसंद करता हूं"। दिलचस्प। और अब मैं WPF ControlTemplates एक सीमा है, मैं काम करने के लिए यह :) –

+0

धन्यवाद के आसपास की कोशिश कर सकते समझता है पता है, मैं अंत में समझ में आ कैसे मेरे ControlTemplate करने के लिए एक शैली लागू करने के लिए। तीसरा उदाहरण रोशनीपूर्ण था और मुझे केवल नियंत्रण टेम्पलेट (ओं) की आवश्यकता के लिए एक शैली लागू करने की अनुमति देता है। –