2010-12-12 14 views
9

पर डब्ल्यूपीएफ में बटन पृष्ठभूमि ओवरराइड करना, इसलिए इच्छा सरल है, लाइटग्रीन, ग्रीन पर बटन की पृष्ठभूमि बदलें जब माउस कर्सर उस पर हो जाता है और डार्कग्रीन दबाया जाता है। निम्नलिखित एक्सएएमएल मेरा पहला प्रयास है:एरो

<Window x:Class="ButtonMouseOver.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <Button Background="LightGreen"> 
     Hello 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

लेकिन, यह काम नहीं करता है। हम लक्ष्य की दिशा में केवल 1/3 रास्ते हैं। हां, बटन हल्का हरा हो जाता है, लेकिन जैसे ही आप इसे घुमाते हैं या इसे दबाते हैं, आपको संबंधित बटन राज्यों के लिए मानक एयरो क्रोम मिलता है।

... 
    <Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
      Background="LightGreen"> 
     Hello 
     <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" 
      x:Name="Chrome" Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}" 
      RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" 
      > 
      <ContentPresenter Margin="{TemplateBinding Padding}" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              RecognizesAccessKey="True" 
              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </Microsoft_Windows_Themes:ButtonChrome> 
     </ControlTemplate> 
     </Button.Template> 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
... 

अब हम मिल गया है वहाँ में फेंक दिया पूरे 'friggin नियंत्रण टेम्पलेट Aero.NormalColor.xaml से उठाया: देने के लिए नहीं चाहते, मैं निम्नलिखित ऐयाशी का प्रयास। हां, यह कुछ भी नहीं बदलता है। मैं Microsoft_Windows_Themes:ButtonChrome तत्व से दो विशेषताओं (RenderPressed और RenderMouseOver) को हटाने के बारे में जाता हूं। फिर भी, कोई बदलाव नहीं है। मैं तो बटन Background विशेषता की स्थापना हटाने, PresentationFramework.Aero विधानसभा के लिए सिर्फ नाम स्थान घोषणा छोड़ने:

... 
<Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"> 
    Hello 
... 

अंत में, हम प्रगति की है। हम आवश्यकताओं के 1/3 से 2/3 तक गए हैं, IsMouseOver और Ispressed काम कर रहे हैं, लेकिन बटन की सामान्य स्थिति के दौरान कोई हल्का हरा पृष्ठभूमि नहीं है (क्योंकि इसे हटाया या दबाया नहीं जा रहा है), क्योंकि मैंने हटा दिया है बटन से पृष्ठभूमि संपत्ति, अन्य दो राज्यों को लागू करने और दिखाई देने के लिए। अब, इस maniacal XAML के बाद हमें सामान्य बटन राज्य के लिए LightGreen पृष्ठभूमि प्राप्त करने के लिए विफल रहता है, मैं शैली वहाँ रूप में अच्छी तरह पृष्ठभूमि रंग फेंकने के लिए संशोधित:

<Button xmlns... 
    <ControlTemplate... 
    ... 
    </ControlTemplate> 
    <Button.Style> 
     <Style TargetType="Button"> 
     <!-- ##### Normal state button background added ##### --> 
     <Setter Property="Background" Value="LightGreen" /> 
     <!-- ################################################ --> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
      <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
      <Setter Property = "Background" Value="DarkGreen"/> 
      </Trigger> 
     </Style.Triggers> 
     </Style> 
    </Button.Style> 
    </Button> 

अंत में, यह के रूप में इरादा काम करता है।

क्या मैं पागल हूं, या ये (और अधिक) हैं जो आपको एरो थीम के साथ गुजरने के लिए हैं, बस अपने कुछ विभिन्न राज्यों (सामान्य, ढके हुए, दबाए गए) में बटन के पृष्ठभूमि रंग को बदलने के लिए? शायद, जीवन इतना बुरा नहीं होगा अगर मुझे वहां से दो विशेषताओं (RenderMouseOver और RenderPressed) को हटाने के लिए पूरे डांग बटन टेम्पलेट को शामिल करने की आवश्यकता नहीं है।

किसी भी मदद के लिए धन्यवाद - मैं बुद्धि के अंत में हूं।

अद्यतन: लेकिन इसके लिए और भी प्रतीक्षा करें।

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... 
    RenderMouseOver="{TemplateBinding IsMouseOver}" 
    RenderPressed="{TemplateBinding IsPressed}" ... 

लिए:

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... 
    RenderMouseOver="{Binding IsMouseOver}" 
    RenderPressed="{Binding IsPressed}" ... 

..., यह भी समस्या (अनदेखी बटन की शैली से चलाता है के) ठीक करता है इसके बजाय RenderMouseOver को दूर करने और RenderPressed नियंत्रण टेम्पलेट से जिम्मेदार बताते हैं, केवल उन लोगों से बदल रहा है । मुझे लगता है कि इस मुद्दे की जड़ यह है कि टेम्पलेट बाइंडिंग संकलन समय (प्रदर्शन कारणों से) पर लागू होती है, जबकि नियमित बाइंडिंग रन टाइम पर लागू होती है। इस वजह से, अलग-अलग बटनों से शैली ट्रिगर्स से बाइंडिंग का उपयोग नहीं किया जाता है यदि विशेषताएँ टेम्पलेट बाइंडिंग का उपयोग करती हैं (यानी, IsMouseOver और मूल टेम्पलेट से दबाया जाता है)।

ऊपर के सभी कहा है, यहां एयरो में एक बटन की पृष्ठभूमि बदलते समय अपने मूल नियंत्रण टेम्पलेट रखने के लिए विहित उदाहरण है:

<Window x:Class="ButtonMouseOver.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <Button> 
     Hello 
     <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" 
      x:Name="Chrome" Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}" 
      RenderMouseOver="{Binding IsMouseOver}" RenderPressed="{Binding IsPressed}" 
      > 
      <ContentPresenter Margin="{TemplateBinding Padding}" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              RecognizesAccessKey="True" 
              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </Microsoft_Windows_Themes:ButtonChrome> 
     </ControlTemplate> 
     </Button.Template> 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Setter Property="Background" Value="LightGreen"/> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

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

किसी को भी कैसे ओवरराइड को बदलने की जरूरत है कि नियंत्रण टेम्पलेट में केवल दो विशेषताओं के लिए बाइंडिंग के साथ TemplateBinding, हवाई XAML थोक से पूरे क्रोम परिभाषा दोहराए बिना, मैं सभी कान हूँ पर कोई सुझाव है तो।

उत्तर

2

Button के लिए डिफ़ॉल्ट टेम्पलेट ButtonChrome का उपयोग करता है, जो अपना स्वयं का चित्रण करता है। यदि आप डिफ़ॉल्ट रूप से पूरी तरह से छुटकारा पाने के लिए चाहते हैं, तो आपको ButtonChrome के बिना अपना खुद का टेम्पलेट परिभाषित करने की आवश्यकता है। मुझे पता है कि यह थकाऊ लगता है, लेकिन आपको केवल एक बार ऐसा करना होगा: आप अपनी कस्टम शैली को संसाधन शब्दकोश में डाल सकते हैं, और इसे StaticResource के साथ देखें। ध्यान दें कि आप {x:Type Button} का उपयोग करके शैली के कुंजी (x:Key विशेषता)

+0

समस्या के रूप में अपने ऐप के सभी बटनों पर शैली को भी लागू कर सकते हैं समस्या यह है कि मैं बस एक बटन की पृष्ठभूमि बदलना चाहता हूं। एरो क्रोम बटन के सामान्य स्थिति के लिए पृष्ठभूमि बटन विशेषता का उपयोग करके इसे ठीक से संभालता है। लेकिन, यह हैंडलिंग दोषपूर्ण है, क्योंकि पृष्ठभूमि माउसओवर पर वापस आती है और जब बटन दबाया जाता है। उन दो राज्यों में बटन की पृष्ठभूमि बदलने के लिए ऐसा कोई आसान तरीका नहीं है। यह बटन (और शायद अन्य विज़ुअल एलीमेंट्स) में पृष्ठभूमि विशेषता रखने के पूरे उद्देश्य को हरा देता है। –

+0

पृष्ठभूमि संपत्ति सभी नियंत्रणों के लिए आम है, इसलिए यह वैसे भी होगा, लेकिन कुछ भी गारंटी नहीं देता है कि टेम्पलेट इसे ध्यान में रखेगा। मैं एरो थीम के साथ आपकी समस्या का पुनरुत्पादन कर सकता हूं, और लुना थीम के साथ एक ही समस्या है। ऐसा लगता है कि बटन क्रोम कुछ राज्यों के लिए पृष्ठभूमि को ध्यान में नहीं लेता है ... वैसे भी, मुझे नहीं लगता कि मानक बटन क्रोम को अपने रंगों को अनुकूलित करने के लिए डिज़ाइन किया गया है। यदि आप ऐसा करना चाहते हैं, तो क्रोम का उपयोग न करें ... इसके बिना अपना स्वयं का बटन टेम्पलेट बनाना बहुत आसान है। –

+0

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

संबंधित मुद्दे