2010-11-25 8 views
5

मैं सभी नियंत्रण से ButtonBaseकक्षा और उसके वंशजों को शैली कैसे लागू करें?

<Style 
    TargetType="{x:Type ButtonBase}"> 
    <Setter 
     Property="Cursor" 
     Value="Hand" /> 
</Style> 

प्राप्त करने के लिए निम्नलिखित शैली लागू करना चाहते हैं लेकिन ऐसा सिर्फ उसके वंश के लिए नहीं, किसी वर्ग के लिए काम करता है। मैं क्या हासिल करना चाहता हूं?

उत्तर

4

इसका कारण यह है एक तत्व एक शैली स्पष्ट रूप से सौंपा नहीं है जब, WPF FindResource बुला, कुंजी के रूप में तत्व के प्रकार का उपयोग करके अपनी शैली पाता है काम नहीं करता। तथ्य यह है कि आपने एक शैली बनाई है जिसका कुंजी ButtonBase कोई फर्क नहीं पड़ता: डब्ल्यूपीएफ को Button या ToggleButton की कुंजी के साथ शैली मिलती है और इसका उपयोग करती है।

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

दो चीजें हैं जो आप कर सकते हैं। शैलियों की अपनी पदानुक्रम को लागू करने के लिए स्टाइल की BasedOn संपत्ति का उपयोग करके जेन्स ने जो किया है, वह करना है। हालांकि, यह कष्टप्रद है, क्योंकि आपको हर एक प्रकार के लिए शैली परिभाषित करना है; यदि आप नहीं करते हैं, तो उस प्रकार के लिए डिफ़ॉल्ट WPF शैली का उपयोग किया जाएगा।

एक अन्य तरीका StyleSelector का उपयोग करना है जो इस लुकअप व्यवहार को लागू करता है। इस तरह:

public class InheritanceStyleSelector : StyleSelector 
{ 
    public InheritanceStyleSelector() 
    { 
     Styles = new Dictionary<object, Style>(); 
    } 
    public override Style SelectStyle(object item, DependencyObject container) 
    { 
     Type t = item.GetType(); 
     while(true) 
     { 
      if (Styles.ContainsKey(t)) 
      { 
       return Styles[t]; 
      } 
      if (t == typeof(FrameworkElement) || t == typeof(object)) 
      { 
       return null; 
      } 
      t = t.BaseType; 
     } 
    } 

    public Dictionary<object, Style> Styles { get; set; } 
} 

आप इस का एक उदाहरण बना सकते हैं, यह शैलियों का एक सेट देने के लिए, और उसके बाद किसी भी ItemsControl के लिए देते:

<Window x:Class="StyleSelectorDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:StyleSelectorDemo="clr-namespace:StyleSelectorDemo" Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <StyleSelectorDemo:InheritanceStyleSelector x:Key="Selector"> 
      <StyleSelectorDemo:InheritanceStyleSelector.Styles> 
       <Style x:Key="{x:Type ButtonBase}"> 
        <Setter Property="ButtonBase.Background" 
          Value="Red" /> 
       </Style> 
       <Style x:Key="{x:Type ToggleButton}"> 
        <Setter Property="ToggleButton.Background" 
          Value="Yellow" /> 
       </Style> 
      </StyleSelectorDemo:InheritanceStyleSelector.Styles> 
     </StyleSelectorDemo:InheritanceStyleSelector> 
    </Window.Resources> 
    <Grid> 
     <ItemsControl ItemContainerStyleSelector="{StaticResource Selector}"> 
      <Button>This is a regular Button</Button> 
      <ToggleButton>This is a ToggleButton.</ToggleButton> 
      <TextBox>This uses WPF's default style.</TextBox> 
     </ItemsControl> 
    </Grid> 
</Window> 
1

यह वास्तव में स्टाइल सिस्टम की एक सीमा प्रतीत होता है।

इस समस्या का सामना करते हुए, मैंने कुछ आधार शैली घोषित की, और हर वंश के लिए "उप-स्टाइल" की परवाह की।

<Style x:Key="ButtonBaseStyle" TargetType="{x:Type ButtonBase}"> 
    <!-- Style stuff --> 
</Style> 
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBaseStyle}"> 
    <!-- Additional style stuff for button only --> 
</Style> 
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource ButtonBaseStyle}"> 
    <!-- Additional style stuff for toggle button only --> 
</Style> 
<!-- more ButtonBase descendants here --> 
संबंधित मुद्दे