2009-01-04 27 views
29

मैं एक कस्टम नियंत्रण बनाने की कोशिश कर रहा हूं - एक बटन - जिसमें डेटा संदर्भ के भीतर किसी संपत्ति के मूल्य के आधार पर कई शैलियों को लागू किया जाएगा।WPF शैलियों के लिए बाध्यकारी

क्या मैं सोच रहा था करने के लिए कुछ इसी तरह उपयोग कर रहा है:

<Button Style="{Binding Path=ButtonStyleProperty, Converter={StaticResource styleConverter}}" Text="{Binding Path=TextProp}" /> 

और कोड में ... एक IValueConverter जो ConvertTo विधि में नीचे दिए गए कोड को कुछ ऐसा ही लागू:

switch(value as ValueEnums) 
{ 
    case ValueEnums.Enum1: 
     FindResource("Enum1ButtonStyle") as Style; 
    break; 

    ... and so on. 
} 

हालांकि मैं पूरी तरह से स्टाइल ऑब्जेक्ट को खींचने के बारे में पूरी तरह से सुनिश्चित नहीं हूं और यहां तक ​​कि यदि यह संभव है ...

मैं टी में क्या कर रहा हूं उनका मतलब है कि समय DataContextChanged ईवेंट को संभालने वाला है, फिर बटन को बाध्य होने वाली ऑब्जेक्ट की PropertyChanged ईवेंट में एक हैंडलर संलग्न करना - फिर वहां स्विच कथन चला रहा है।

यह बिल्कुल सही नहीं है, लेकिन जब तक मैं एक बेहतर समाधान नहीं ढूंढ पाता, ऐसा लगता है कि मुझे इसका उपयोग करना होगा।

उत्तर

35

आप पूरे शैली (बजाय इसके बारे में सिर्फ तत्वों) को बदलने के लिए चाहते हैं तो आपको हूँ शायद संसाधनों में उन शैलियों को संग्रहित किया जा रहा है। आप की तर्ज पर कुछ करने के लिए सक्षम होना चाहिए:

<Button> 
    <Button.Style> 
     <MultiBinding Converter="{StaticResource StyleConverter}"> 
      <MultiBinding.Bindings> 
       <Binding RelativeSource="{RelativeSource Self}"/> 
       <Binding Path="MyStyleString"/> 
      </MultiBinding.Bindings> 
     </MultiBinding> 
    </Button.Style> 
</Button> 

एक MultiBinding का उपयोग कर और स्वयं का उपयोग करके के रूप में पहली बाध्यकारी हम तो हमारे कनवर्टर में संसाधनों देखने कर सकते हैं। कनवर्टर IMultiValueConverter (बजाय IValueConverter) लागू करने के लिए और कुछ इस तरह देख सकते हैं की जरूरत है: कि स्मृति :)

+0

धन्यवाद स्टीव - यह वही किया जो मैं करने की कोशिश कर रहा था :) –

+0

कोई चिंता नहीं। डब्ल्यूपीएफ में सब कुछ के साथ, ऐसा करने के लिए शायद 10 और रास्ते हैं, लेकिन इस तरह से बहुत साफ और "डिजाइनर अनुकूल" लगता है :) –

+0

धन्यवाद! मैं स्ट्रिंगटो स्टाइल कनवर्टर के लिए इन लाइनों के साथ कुछ पता लगाने की कोशिश कर रहा था और इस पर आया जो महान काम करता था। – Rachel

14

ऐसा लगता है कि आपको DataTrigger कक्षा का उपयोग करने की आवश्यकता है। यह आपको अपनी सामग्री के आधार पर अपने बटन पर विभिन्न शैलियों को लागू करने की अनुमति देता है।

उदाहरण निम्नलिखित शैली लाल करने के लिए बटन की पृष्ठभूमि संपत्ति बदल जाएगा के लिए डेटा संदर्भ वस्तु की संपत्ति के मूल्य के आधार पर

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path="Some property"}" 
        Value="some property value"> 
      <Setter Property="Background" Value="Red"/> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 
+0

में निम्न कोड आप सही के आंकड़ों के आधार पर शैलियाँ लागू करने में सक्षम होने के साथ हैं बाध्य संदर्भ मैं पूरी तरह शैलियों को पूरी तरह से स्विच करना पसंद करूंगा - अन्यथा वे बहुत ही जटिल हो जाते हैं ... –

8

से काम करना चाहिए

class StyleConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     FrameworkElement targetElement = values[0] as FrameworkElement; 
     string styleName = values[1] as string; 

     if (styleName == null) 
      return null; 

     Style newStyle = (Style)targetElement.TryFindResource(styleName); 

     if (newStyle == null) 
      newStyle = (Style)targetElement.TryFindResource("MyDefaultStyleName"); 

     return newStyle; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

यह कुछ मैं बहुत बार ऐसा नहीं है, लेकिन हम में से उन लोगों के लिए जो बहु मूल्य कनवर्टर का उपयोग नहीं कर सकता (मैं आपको SL4 और WP7 देख रहा हूं :), स्टीवन के उत्तर के लिए धन्यवाद, मुझे एक सामान्य मूल्य कनवर्टर का उपयोग करने का एक तरीका मिला।

एकमात्र धारणा शैली शैली निर्धारित शैली की संपत्ति के भीतर निहित है।

तो यदि आप एमवीवीएम पैटर्न का उपयोग कर रहे हैं तो शैली मूल्य (जैसे टेक्स्टस्माल, टेक्स्टमेडियम, टेक्स्टलार्ज) को दृश्य मॉडल का हिस्सा माना जाता है, और आपको बस इतना करना है कि नाम परिभाषित कनवर्टर पैरामीटर शैली का

उदाहरण के लिए, आपके विचार मॉडल संपत्ति है:

public string ProjectNameStyle 
{ 
    get { return string.Format("ProjectNameStyle{0}", _displaySize.ToString()); } 
} 

आवेदन शैली:

<Application.Resources> 
    <Style x:Key="ProjectNameStyleSmall" TargetType="TextBlock"> 
     <Setter Property="FontSize" Value="40" /> 
    </Style> 
    <Style x:Key="ProjectNameStyleMedium" TargetType="TextBlock"> 
     <Setter Property="FontSize" Value="64" /> 
    </Style> 
    <Style x:Key="ProjectNameStyleLarge" TargetType="TextBlock"> 
     <Setter Property="FontSize" Value="90" /> 
    </Style> 

XAML दृश्य:

<TextBlock 
     Text="{Binding Name}" 
     Style="{Binding ., Mode=OneWay, Converter={cv:StyleConverter}, ConverterParameter=ProjectNameStyle}"> 
अपने StyleConverter वर्ग IValueConverter को लागू करने के साथ

:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (targetType != typeof(Style)) 
    { 
     throw new InvalidOperationException("The target must be a Style"); 
    } 

    var styleProperty = parameter as string; 
    if (value == null || styleProperty == null) 
    { 
     return null; 
    } 

    string styleValue = value.GetType() 
     .GetProperty(styleProperty) 
     .GetValue(value, null) 
     .ToString(); 
    if (styleValue == null) 
    { 
     return null; 
    } 

    Style newStyle = (Style)Application.Current.TryFindResource(styleValue); 
    return newStyle; 
} 

ध्यान दें कि यह डब्ल्यूपीएफ कोड है, क्योंकि कनवर्टर मार्कअप एक्सटेंशन के साथ-साथ IValueConverter से लिया गया है, लेकिन यदि आप स्थैतिक संसाधन का उपयोग करते हैं और थोड़ा और अधिक काम करते हैं तो TryFindResource विधि नहीं करता है, यह एसएल 4 और WP7 में काम करेगा। टी मौजूद नहीं है।

आशा है कि किसी की मदद करें, और फिर स्टीवन धन्यवाद!

1

ViewModel

private Style _dynamicStyle = (Style)Application.Current.FindResource("Style1"); 
     public Style DynamicStyle 
     { 
      get { return _dynamicStyle; } 
      set 
      { 
       _dynamicStyle = value; 
       OnPropertyChanged("DynamicStyle"); 
      } 

     } 

public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

अपने ViewModel में एक संपत्ति को लागू करें और फिर गतिशील शैली जहां कभी आप नीचे दिए गए की तरह चाहते हैं बदल जाते हैं।

DynamicStyle=(Style)Application.Current.FindResource("Style2");// you can place this code where the action get fired 

देखें

फिर DataContext मान सेट और फिर अपने दृश्य

<Button Style="{Binding DynamicStyle,Mode=TwoWay}"/> 
+0

क्या यह एमवीवीएम पैटर्न का उल्लंघन नहीं है? चूंकि वीएम अब एक शैली के बारे में जानता है। –

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