WPF में StaticResource और DynamicResource के बीच क्या अंतर है?


473

WPF में ब्रश, टेम्प्लेट और शैलियों जैसे संसाधनों का उपयोग करते समय, उन्हें या तो StaticResources के रूप में निर्दिष्ट किया जा सकता है

<Rectangle Fill="{StaticResource MyBrush}" />

या एक डायनामिक स्रोत के रूप में

<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}"  />

अधिकांश समय (हमेशा?), केवल एक काम करता है और दूसरा रनटाइम के दौरान अपवाद फेंक देगा। लेकिन मैं जानना चाहूंगा कि क्यों:

  • मुख्य अंतर क्या है स्मृति या प्रदर्शन निहितार्थ की तरह
  • क्या WPF में नियम हैं जैसे "ब्रश हमेशा स्थिर होते हैं" और "टेम्पलेट हमेशा गतिशील होते हैं" आदि?

मुझे लगता है कि स्टेटिक बनाम डायनामिक के बीच का विकल्प उतना मनमाना नहीं है जितना कि लगता है ... लेकिन मैं पैटर्न को देखने में असफल हूं।


27
यह ध्यान रखना महत्वपूर्ण है कि विंडोज 8 ऐप डेवलपर्स के पास केवल विकल्प के रूप में DyanmicResource नहीं है, केवल StaticResource।
जैरी निक्सन

2
@ जेरी निक्सन भगवान का शुक्र है कि, मैंने कई बार काम करने के लिए कुछ भी हासिल नहीं किया, क्योंकि मैं स्टैटिकऑन सोर्स के बजाय डायनामिक सोर्स का उपयोग कर रहा था या इसके विपरीत। प्रोग्रामर के दृष्टिकोण से, यह अनावश्यक जटिलता है। एक सादृश्य परिवर्तनशील परिभाषा है, क्या मुझे स्पष्ट रूप से निर्दिष्ट करना चाहिए कि क्या यह ढेर या स्टैक पर रहता है? और अगर मुझे यह गलत लगता है तो यह एक भयावह रनटाइम त्रुटि फेंकता है?
कंटैंगो

StaticResource और DynamicResource की अधिक गहन व्याख्या के लिए, और प्रत्येक का उपयोग करने के लिए, msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx देखें ।
माइकल रेपुची

जवाबों:


466

XAML की लोडिंग के दौरान एक StaticResource हल हो जाएगा और संपत्ति को सौंपा जाएगा जो वास्तव में आवेदन से पहले होता है। इसे केवल एक बार सौंपा जाएगा और संसाधन शब्दकोश में किसी भी परिवर्तन को अनदेखा कर दिया जाएगा।

एक डायनामिक स्रोत लोडिंग के दौरान संपत्ति के लिए एक अभिव्यक्ति वस्तु प्रदान करता है, लेकिन वास्तव में संसाधन को तब तक नहीं देखता है जब मूल्य के लिए अभिव्यक्ति ऑब्जेक्ट पूछा जाता है। यह तब तक संसाधन की तलाश करता है जब तक कि इसे रनटाइम की आवश्यकता न हो। एक अच्छा उदाहरण XAML में बाद में परिभाषित एक संसाधन का एक आगे का संदर्भ होगा। एक अन्य उदाहरण एक संसाधन है जो रनटाइम तक भी मौजूद नहीं होगा। यदि स्रोत संसाधन शब्दकोश परिवर्तित किया गया है तो यह लक्ष्य को अद्यतन करेगा।


4
डायनामिक स्रोत का उपयोग करने से पहले मुझे क्या बदलना होगा? उदाहरण के लिए एक टेम्प्लेट लें: मैं इसे एक बार परिभाषित करता हूं, लेकिन फिर ट्रिगर और सामान टेम्पलेट की सामग्री को बदल सकता है लेकिन टेम्प्लेट अभी भी समान है। क्या StaticResource यहाँ करेगा?
इसक सावो

5
StaticResource का उपयोग करें यदि आप जिस संसाधन को संलग्न कर रहे हैं वह उसके उपयोग से पहले XAML में परिभाषित है और चल रहे आवेदन के जीवनकाल के लिए बदलने वाला नहीं है। उस स्थिति में आपको StaticResource से बेहतर प्रदर्शन मिलता है।
फिल राइट

4
क्या इन दोनों पर बाइंडिंग लागू है, यदि हाँ तो उस मामले में क्या अंतर होगा?
WhoIsNinja

11
अंतिम वाक्य वास्तव में महत्वपूर्ण है:It will update the target if the source resource dictionary is changed.
मेमार्क

4
@IsakSavo रंग विषयों के साथ एक UI पर विचार करें, एक गतिशील संसाधन के साथ, आप एक शब्दकोश को दूसरे के लिए स्वैप कर सकते हैं और नए शब्दकोश में संसाधनों को संदर्भित करने वाले कुछ भी स्वचालित रूप से अपडेट हो जाएंगे।
गुस्सोर

119

मैं भी उनके बारे में उलझन में था। इस उदाहरण को नीचे देखें:

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

    <StackPanel>
        <Button Name="ButtonNew" 
                Click="ButtonNew_Click" 
                Background="{DynamicResource PinkBrush}">NEW</Button>
        <Image Name="ImageNew" 
               Source="pack://application:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

यहां मैंने बटन और विंडो के लिए डायनामिक रिसोर्स का उपयोग किया है और इसे कहीं भी घोषित नहीं किया है। रनटाइम के दौरान, पदानुक्रम के संसाधन छाया की जाँच की जाएगी। क्योंकि मैंने इसे परिभाषित नहीं किया है, मुझे लगता है कि डिफ़ॉल्ट का उपयोग किया जाएगा।

यदि मैं बटन की घटना पर क्लिक करने के लिए नीचे दिए गए कोड को जोड़ता हूं, क्योंकि वे डायनामिक स्रोत का उपयोग करते हैं, तो पृष्ठभूमि तदनुसार अपडेट की जाएगी।

private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
    this.Resources.Add(  "PinkBrush"
                         ,new SolidColorBrush(SystemColors.DesktopColor)
                       );
}

यदि उन्होंने StaticResource का उपयोग किया है:

  • संसाधन XAML में घोषित किया जाना है
  • और वह भी "पहले" उनका उपयोग किया जाता है।

आशा है कि मैंने कुछ भ्रम को दूर किया।


31

StaticResource ऑब्जेक्ट निर्माण पर हल किया जाएगा।
डायनामिक स्रोत का मूल्यांकन और समाधान हर बार संसाधन की आवश्यकता के अनुसार किया जाएगा।


21
  1. StaticResource पहले मान का उपयोग करता है । डायनामिक स्रोत अंतिम मान का उपयोग करता है ।
  2. डायनेमिकResource नेस्टेड स्टाइलिंग के लिए उपयोग किया जा सकता है, StaticResource नहीं कर सकता।

मान लीजिए कि आपके पास यह नेस्टेड स्टाइल शब्दकोश है। लाइटग्रीन जड़ स्तर पर है जबकि पिंक एक ग्रिड के अंदर घोंसला है।

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
                <Setter Property="Background" Value="Pink"/>
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
        <Setter Property="Background" Value="LightGreen"/>
    </Style>
</ResourceDictionary>

दृश्य में:

<Window x:Class="WpfStyleDemo.ConflictingStyleWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ConflictingStyleWindow" Height="100" Width="100">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ConflictingStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Style="{DynamicResource ConflictButton}" Content="Test"/>
    </Grid>
</Window>

StaticResource बटन को लाइटग्रीन के रूप में प्रस्तुत करेगा, यह शैली में पहला मूल्य है। डायनामिक स्रोत लाइटग्रिन बटन को गुलाबी के रूप में ओवरराइड करेगा क्योंकि यह ग्रिड को प्रस्तुत करता है।

StaticResource StaticResource

DynamicResource DynamicResource

ध्यान रखें कि VS डिज़ाइनर डायनामिक सोर्स को StaticResource मानते हैं। इसका पहला मूल्य मिलेगा। इस मामले में, वीएस डिज़ाइनर बटन को लाइटग्रीन के रूप में प्रस्तुत करेगा, हालांकि यह वास्तव में गुलाबी के रूप में समाप्त होता है।

जब रूट-स्तरीय शैली (लाइटग्रीन) को हटा दिया जाता है, तो StaticResource एक त्रुटि फेंक देगा।


13

मुख्य अंतर क्या है स्मृति या प्रदर्शन निहितार्थ की तरह

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

स्टेटिक रिसोर्स को एक बार संदर्भित तत्व द्वारा प्राप्त किया जाता है और संसाधनों के जीवनकाल के लिए उपयोग किया जाता है। जबकि, डायनामिक स्रोत हर बार उपयोग किए जाने के बाद पुनः प्राप्त करते हैं।

डायनामिक संसाधनों का नकारात्मक पक्ष यह है कि वे अनुप्रयोग प्रदर्शन को कम करते हैं।

क्या WPF में नियम हैं जैसे "ब्रश हमेशा स्थिर होते हैं" और "टेम्पलेट हमेशा गतिशील होते हैं" आदि?

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


7

सभी उत्तर उपयोगी मिले, बस एक और उपयोग के मामले को जोड़ना चाहता था।

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

जैसा कि दूसरों ने उल्लेख किया है, स्टैटिकसोर्स को संकलन के समय देखा जाएगा। उपयोगकर्ता नियंत्रण उन संसाधनों को संदर्भित नहीं कर सकते हैं जो होस्टिंग / अभिभावक नियंत्रण में परिभाषित हैं। हालाँकि, इस मामले में डायनामिक स्रोत का उपयोग किया जा सकता है।


3

गतिशील संसाधनों का महत्वपूर्ण लाभ

यदि एप्लिकेशन स्टार्टअप में बहुत लंबा समय लगता है, तो आपको गतिशील संसाधनों का उपयोग करना चाहिए, क्योंकि स्थिर संसाधन हमेशा लोड किए जाते हैं जब विंडो या ऐप बनाया जाता है, जबकि गतिशील संसाधन लोड किए जाते हैं जब वे पहली बार उपयोग किए जाते हैं।

हालाँकि, आपको कोई लाभ तब तक नहीं दिखेगा जब तक कि आपका संसाधन बहुत बड़ा और जटिल न हो।


डायनामिक स्रोत के लिए, क्या यह केवल एक बार (पहली बार उपयोग किया गया) एक प्रदर्शन समस्या पैदा कर रहा है या क्या प्रत्येक बार तत्व का उपयोग किया जाता है?
मॉर्गन

इस स्थिति में अधिकांश उपयोग किए जाने वाले फ़ील्ड स्थिर संसाधन होने चाहिए, कस्टम उपयोग किए गए फ़ील्ड गतिशील हो सकते हैं, यानी मेनविंडो संसाधनों के लिए स्थिर और डायलॉग विंडो संसाधन गतिशील हो सकते हैं
zamoldar

2

डायनामिक संसाधनों का उपयोग केवल तब किया जा सकता है जब सेट की जा रही वस्तु ऑब्जेक्ट पर होती है जो निर्भरता ऑब्जेक्ट या फ्रीज़ेबल से प्राप्त होती है जहां स्थिर संसाधनों का उपयोग कहीं भी किया जा सकता है। आप स्थैतिक संसाधनों का उपयोग करके संपूर्ण नियंत्रण को समाप्त कर सकते हैं।

स्थैतिक संसाधनों का उपयोग निम्नलिखित परिस्थितियों में किया जाता है:

  1. जब रनटाइम पर प्रतिक्रिया संसाधन में बदलाव की आवश्यकता नहीं होती है।
  2. यदि आपको बहुत सारे संसाधनों के साथ एक अच्छे प्रदर्शन की आवश्यकता है।
  3. एक ही शब्दकोश के भीतर संसाधनों का संदर्भ देते हुए।

गतिशील संसाधन:

  1. संपत्ति या स्टाइल सेटर थीम का मूल्य रनटाइम तक ज्ञात नहीं है
    • इसमें सिस्टम, एप्लायंस, थीम आधारित सेटिंग्स शामिल हैं
    • इसमें आगे के संदर्भ भी शामिल हैं।
  2. बड़े संसाधनों को संदर्भित करना जो पेज, विंडोज़, उपयोगकर्ता कॉन्ट्रॉल लोड होने पर लोड नहीं हो सकता है।
  3. एक कस्टम नियंत्रण में थीम शैलियों को संदर्भित करना।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.