.net - WPF में एकाधिक शैलियों को कैसे लागू करें




styles (7)

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


अपनी शैलियों का उपयोग और लपेटने के लिए एक सहायक वर्ग बनाकर यह संभव है। here वर्णित कंपाउंड स्टाइल दिखाता है कि यह कैसे करें। कई तरीके हैं, लेकिन निम्नतम करना सबसे आसान है:

<TextBlock Text="Test"
    local:CompoundStyle.StyleKeys="headerStyle,textForMessageStyle,centeredStyle"/>

उम्मीद है की वो मदद करदे।


कभी-कभी आप घोंसले पैनलों से इसका संपर्क कर सकते हैं। मान लें कि आपके पास एक स्टाइल है जो फोरग्राउंड बदलती है और फ़ॉन्ट्सइज़ में एक और बदलाव बदलती है, आप बाद वाले को टेक्स्टब्लॉक पर लागू कर सकते हैं, और उसे ग्रिड में डाल सकते हैं, जिसकी शैली पहली है। इससे कुछ मामलों में सबसे आसान तरीका हो सकता है और हो सकता है, हालांकि यह सभी समस्याओं का समाधान नहीं करेगा।


डब्ल्यूपीएफ / एक्सएएमएल इस कार्यक्षमता को मूल रूप से प्रदान नहीं करता है, लेकिन यह आपको अपनी इच्छित चीज़ों को करने की अनुमति देने के लिए एक्स्टेंसिबिलिटी प्रदान करता है।

हम एक ही ज़रूरत में भाग गए, और हमारे स्वयं के एक्सएएमएल मार्कअप एक्सटेंशन (जिसे हमने "मर्ज स्टाइल एक्सटेन्शन" कहा) बनाने के लिए समाप्त किया ताकि हमें दो अन्य शैलियों से एक नई शैली बनाने की अनुमति मिल सके (जो, यदि आवश्यक हो, तो शायद कई बार इस्तेमाल किया जा सकता है पंक्तियों को और भी शैलियों से प्राप्त करने के लिए)।

एक डब्ल्यूपीएफ / एक्सएएमएल बग के कारण, हमें इसका उपयोग करने के लिए प्रॉपर्टी एलिमेंट सिंटैक्स का उपयोग करने की आवश्यकता है, लेकिन इसके अलावा यह ठीक काम करता है। उदाहरण के लिए,

<Button
    Content="This is an example of a button using two merged styles">
    <Button.Style>
      <ext:MergedStyles
                BasedOn="{StaticResource FirstStyle}"
                MergeStyle="{StaticResource SecondStyle}"/>
   </Button.Style>
</Button>

मैंने हाल ही में इसके बारे में यहां लिखा है: http://swdeveloper.wordpress.com/2009/01/03/wpf-xaml-multiple-style-inheritance-and-markup-extensions/


निम्नलिखित कोड जैसे कई शैलियों को सेट करने के लिए AttachedProperty का उपयोग करें:

public class Css
{

    public static string GetClass(DependencyObject element)
    {
        if (element == null)
            throw new ArgumentNullException("element");

        return (string)element.GetValue(ClassProperty);
    }

    public static void SetClass(DependencyObject element, string value)
    {
        if (element == null)
            throw new ArgumentNullException("element");

        element.SetValue(ClassProperty, value);
    }


    public static readonly DependencyProperty ClassProperty =
        DependencyProperty.RegisterAttached("Class", typeof(string), typeof(Css), 
            new PropertyMetadata(null, OnClassChanged));

    private static void OnClassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var ui = d as FrameworkElement;
        Style newStyle = new Style();

        if (e.NewValue != null)
        {
            var names = e.NewValue as string;
            var arr = names.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var name in arr)
            {
                Style style = ui.FindResource(name) as Style;
                foreach (var setter in style.Setters)
                {
                    newStyle.Setters.Add(setter);
                }
                foreach (var trigger in style.Triggers)
                {
                    newStyle.Triggers.Add(trigger);
                }
            }
        }
        ui.Style = newStyle;
    }
}

Usege:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:style_a_class_like_css"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="325">
    <Window.Resources>

        <Style TargetType="TextBlock" x:Key="Red" >
            <Setter Property="Foreground" Value="Red"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Green" >
            <Setter Property="Foreground" Value="Green"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Size18" >
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="Margin" Value="6"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Bold" >
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>

    </Window.Resources>
    <StackPanel>

        <Button Content="Button" local:Css.Class="Red Bold" Width="75"/>
        <Button Content="Button" local:Css.Class="Red Size18" Width="75"/>
        <Button Content="Button" local:Css.Class="Green Size18 Bold" Width="75"/>

    </StackPanel>
</Window>

परिणाम:


यदि आप किसी विशिष्ट गुण को छू नहीं रहे हैं, तो आप शैली के लिए सभी आधार और सामान्य गुण प्राप्त कर सकते हैं, जिसका लक्ष्य प्रकार फ्रेमवर्क एलिमेंट होगा। फिर, आप उन सभी सामान्य गुणों की प्रतिलिपि बनाने की आवश्यकता के बिना, प्रत्येक लक्ष्य प्रकार के लिए विशिष्ट स्वाद बना सकते हैं।


लेकिन आप दूसरे से विस्तार कर सकते हैं .. आधारितऑन संपत्ति पर एक नज़र डालें

<Style TargetType="TextBlock">
      <Setter Property="Margin" Value="3" />
</Style>

<Style x:Key="AlwaysVerticalStyle" TargetType="TextBlock" 
       BasedOn="{StaticResource {x:Type TextBlock}}">
     <Setter Property="VerticalAlignment" Value="Top" />
</Style>

मुझे लगता है कि सरल जवाब यह है कि आप ऐसा नहीं कर सकते (कम से कम WPF के इस संस्करण में) जो आप करने की कोशिश कर रहे हैं।

यही है, किसी विशेष तत्व के लिए केवल एक शैली लागू की जा सकती है।

हालांकि, जैसा कि अन्य ने ऊपर बताया है, शायद आप मदद करने के लिए BasedOn का उपयोग कर सकते हैं। ढीले xaml के निम्नलिखित टुकड़े देखें। इसमें आप देखेंगे कि मेरे पास आधार शैली है जो उस तत्व को स्थापित कर रही है जो तत्व के आधार वर्ग पर मौजूद है जिसे मैं दो शैलियों को लागू करना चाहता हूं। और, दूसरी शैली में जो आधार शैली पर आधारित है, मैंने एक और संपत्ति निर्धारित की है।

तो, यहां विचार ... यदि आप किसी भी तरह से उन गुणों को अलग कर सकते हैं जिन्हें आप सेट करना चाहते हैं ... तत्व के विरासत पदानुक्रम के अनुसार आप कई शैलियों को सेट करना चाहते हैं ... आपके पास एक कामकाज हो सकता है।

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <Style x:Key="baseStyle" TargetType="FrameworkElement">
            <Setter Property="HorizontalAlignment" Value="Left"/>
        </Style>
        <Style TargetType="Button" BasedOn="{StaticResource baseStyle}">
            <Setter Property="Content" Value="Hello World"/>
        </Style>
    </Page.Resources>
    <Grid>
        <Button Width="200" Height="50"/>
    </Grid>
</Page>


उम्मीद है की यह मदद करेगा।

ध्यान दें:

विशेष रूप से ध्यान देने योग्य एक बात। यदि आप दूसरी शैली में ButtonBase हैं (ऊपर xaml के पहले सेट में) ButtonBase , दो शैलियाँ लागू नहीं होती हैं। हालांकि, उस प्रतिबंध को पाने के लिए नीचे दिए गए xaml को देखें। असल में, इसका मतलब है कि आपको शैली को एक कुंजी देने और उस कुंजी के साथ संदर्भित करने की आवश्यकता है।

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <Style x:Key="baseStyle" TargetType="FrameworkElement">
            <Setter Property="HorizontalAlignment" Value="Left"/>
        </Style>
        <Style x:Key="derivedStyle" TargetType="ButtonBase" BasedOn="{StaticResource baseStyle}">
            <Setter Property="Content" Value="Hello World"/>
        </Style>
    </Page.Resources>
    <Grid>
        <Button Width="200" Height="50" Style="{StaticResource derivedStyle}"/>
    </Grid>
</Page>




styles