2010-08-06 20 views
8

यदि मेरे पास दो 200 लाइनें लंबे नियंत्रण टेम्पलेट्स हैं जो केवल कुछ शब्दों (कुछ रंग) में भिन्न होती हैं, तो मैं xaml को पुन: प्रयोज्य कैसे बना सकता हूं? यही है, टेम्पलेट को कॉपी-पेस्ट करने और 200 लाइनों में 3 शब्दों को बदलने की आवश्यकता नहीं है।WPF में पैरामीटरेटेड शैली/टेम्पलेट?

यहां एक सरलीकृत उदाहरण है। दोनों शैलियों के बीच एकमात्र अंतर सीमा रंग है। तो क्या मैं किसी भी प्रकार के बटन को एक पैरामीटर रंग के साथ परिभाषित कर सकता हूं, और ब्लैकबटन स्टाइल और ग्रेबटन स्टाइल का अधिग्रहण कर सकता हूं, और ब्लैकबटन स्टाइल और ग्रेबटन स्टाइल में केवल उस रंग को निर्दिष्ट कर सकता हूं?

alt text http://img444.imageshack.us/img444/9545/buttonstyles.png

<Window x:Class="WpfApplication33.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 

     <Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Border BorderBrush="Black" BorderThickness="3"> 
          <ContentControl Content="{TemplateBinding Content}"/> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

     <Style x:Key="GrayButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Border BorderBrush="Gray" BorderThickness="3"> 
          <ContentControl Content="{TemplateBinding Content}"/> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

    </Window.Resources> 
    <StackPanel> 
     <Button Content="Black Button" 
       Style="{StaticResource BlackButtonStyle}"/> 
     <Button Content="Gray Button" 
       Style="{StaticResource GrayButtonStyle}"/> 
    </StackPanel> 
</Window> 

यहाँ 2 उत्तरों के आधार पर कोड है। केवल एक शैली नियंत्रण पर निर्धारित करने की आवश्यकता, लेकिन दुर्भाग्य से यह अभी भी नियंत्रण के टैग को खराब करता:

<Window x:Class="WpfApplication33.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 

     <Style x:Key="ButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Border Name="border" 
           BorderBrush="Black" 
           BorderThickness="3"> 
          <ContentControl Content="{TemplateBinding Content}"/> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="Tag" Value="Gray"> 
           <Setter TargetName="border" 
             Property="BorderBrush" 
             Value="Gray"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

     <Style x:Key="BlackButtonStyle" 
       TargetType="{x:Type Button}" 
       BasedOn="{StaticResource ButtonStyle}"/> 
     <Style x:Key="GrayButtonStyle" 
       TargetType="{x:Type Button}" 
       BasedOn="{StaticResource ButtonStyle}"> 
      <Setter Property="Tag" Value="Gray"/> 
     </Style> 

    </Window.Resources> 
    <StackPanel> 
     <Button Content="Black Button" 
       Style="{StaticResource BlackButtonStyle}"/> 
     <Button Content="Gray Button" 
       Style="{StaticResource GrayButtonStyle}"/> 
    </StackPanel> 
</Window> 

उत्तर

3

सही तरीके से इस बारे में जाने के लिए वर्ग कि पकड़ कर सकते हैं पर एक DependencyProperty बनाने के लिए आमतौर पर है parametrized डेटा, और फिर अपने टेम्पलेट में उस संपत्ति से बांधें। एक त्वरित उदाहरण बनाने के लिए, मैं Button.Tag संपत्ति है, जो एक ब्रश के रूप में सरल कुछ संग्रहीत करने के लिए पूरी तरह से अच्छी तरह से काम का उपयोग करने के लिए जा रहा हूँ:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
<Page.Resources> 
    <SolidColorBrush x:Key="BlackBrush" Color="Black"/> 
    <SolidColorBrush x:Key="GrayBrush" Color="Gray"/> 
    <Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Border BorderBrush="{TemplateBinding Tag}" BorderThickness="3"> 
         <ContentControl Content="{TemplateBinding Content}"/> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Page.Resources> 

<StackPanel> 
    <Button Content="Black Button" Tag="{StaticResource BlackBrush}" 
      Style="{StaticResource CustomButtonStyle}"/> 
    <Button Content="Gray Button" Tag="{StaticResource GrayBrush}" 
      Style="{StaticResource CustomButtonStyle}"/> 
</StackPanel> 

+0

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

+0

आप आसानी से UserControl बना सकते हैं जो इन सभी को encapsulates और रंग सेट करने के लिए निर्भरता प्रॉपर्टी प्रदान करता है। तब आपके पास कोई डुप्लिकेट कोड नहीं होगा। लेकिन आप अतिरिक्त डेटा स्टोर करने के लिए किसी प्रकार की अलग इकाई बनाने से नहीं बच सकते हैं। – Charlie

4

जबकि उनके उदाहरण के बारे में चार्ली सही, आपके विशिष्ट मामले के लिए मैं केवल BorderThickness और BorderBrush गुणों का उपयोग करता हूं जो एक बटन पहले से ही खुलासा करता है: आप अपनी खुद की संपत्ति बनाने के बजाय {TemplateBinding BorderBrush} का उपयोग कर सकते हैं।

संपादित करें: नमूना XAML ... ध्यान दें कि मेरी शैली चूक रंग & मोटाई, लेकिन इन इनलाइन अधिरोहित जा सकता है ...

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
<Page.Resources> 
    <SolidColorBrush x:Key="BlackBrush" Color="Black"/> 
    <SolidColorBrush x:Key="GrayBrush" Color="Gray"/> 
    <Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}"> 
     <Setter Property="BorderThickness" Value="3" /> 
     <Setter Property="BorderBrush" Value="{StaticResource BlackBrush}" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderColor="{TemplateBinding BorderThickness}"> 
         <ContentControl Content="{TemplateBinding Content}"/> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Page.Resources> 

<StackPanel> 
    <Button Content="Black Button" BorderBrush="{StaticResource BlackBrush}" 
      Style="{StaticResource CustomButtonStyle}"/> 
    <Button Content="Gray Button" BorderBrush="{StaticResource GrayBrush}" 
      Style="{StaticResource CustomButtonStyle}"/> 
</StackPanel> 
+0

मुझे इस मामले में सबसे अच्छा समाधान की तरह * लगता है * यह कल्पना करने में परेशानी हो रही है। क्या आप यह बता सकते हैं कि यह कोड में कैसे दिखेगा? – Berryl

+0

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

+0

हाँ, ठंडा। अगर यह मेरा सवाल था तो मैं इसे उत्तर के रूप में चिह्नित करूंगा! चियर्स – Berryl

2

this solution पर एक नज़र डालें, यह सटीक मुद्दा आप 'को हल करती है फिर से हो रहा है

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