WPF में एक निर्भरता संपत्ति और एक संलग्न संपत्ति के बीच अंतर क्या है?


91

WPF में (कस्टम) निर्भरता संपत्ति और संलग्न संपत्ति के बीच अंतर क्या है? प्रत्येक के लिए उपयोग क्या हैं? आमतौर पर कार्यान्वयन कैसे भिन्न होते हैं?

जवाबों:


20

सार

चूंकि मुझे इस मामले पर कोई दस्तावेज नहीं मिला, इसलिए स्रोत कोड के आसपास कुछ प्रहार हुआ , लेकिन यहां एक जवाब है।

एक नियमित रूप से और एक संलग्न संपत्ति के रूप में एक निर्भरता संपत्ति को पंजीकृत करने के बीच एक अंतर है, एक "दार्शनिक" एक के अलावा ( नियमित गुणों को घोषित प्रकार और इसके व्युत्पन्न प्रकारों द्वारा उपयोग किए जाने का इरादा है, संलग्न गुणों का उपयोग करने का इरादा है। मनमाना DependencyObject उदाहरणों पर विस्तार )। "दार्शनिक", क्योंकि, @MarqueIV ने अपनी टिप्पणी में @ ReedCopsey के उत्तर पर ध्यान दिया, नियमित गुणों का उपयोग मनमाने DependencyObjectउदाहरणों के साथ भी किया जा सकता है ।

इसके अलावा, मुझे लगता है कि संलग्न संपत्ति "निर्भरता संपत्ति का प्रकार" बताते हुए अन्य उत्तरों से असहमत है, क्योंकि यह भ्रामक है - निर्भरता गुणों का कोई "प्रकार" नहीं है। यदि संपत्ति संलग्न या पंजीकृत नहीं थी, तो फ्रेमवर्क परवाह नहीं करता है - यह निर्धारित करना भी संभव नहीं है (इस अर्थ में कि यह जानकारी दर्ज नहीं है, क्योंकि यह अप्रासंगिक है)। वास्तव में, सभी संपत्तियों को पंजीकृत किया जाता है जैसे कि वे संलग्न गुण थे, लेकिन नियमित लोगों के मामले में कुछ अतिरिक्त चीजें की जाती हैं जो उनके व्यवहार को थोड़ा संशोधित करती हैं।

कोड का अंश

आपको स्रोत कोड के माध्यम से जाने की परेशानी से बचाने के लिए, यहां एक उबला हुआ संस्करण होता है।

जब निर्दिष्ट मेटाडाटा के बिना एक संपत्ति दर्ज करना, कॉल करना

DependencyProperty.Register(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass))

पैदावार ठीक उसी बुला के रूप में परिणाम

DependencyProperty.RegisterAttached(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass))

हालांकि, मेटाडेटा को निर्दिष्ट करते समय, कॉलिंग

DependencyProperty.Register(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass),
    typeMetadata: new FrameworkPropertyMetadata
    {
        CoerceValueCallback = CoerceCallback,
        DefaultValue = "default value",
        PropertyChangedCallback = ChangedCallback
    });

कॉल करने के बराबर है

var property = DependencyProperty.RegisterAttached(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass),
    defaultMetadata: new PropertyMetadata
    {
        DefaultValue = "default value",
    });
property.OverrideMetadata(
    forType: typeof(MyClass),
    typeMetadata: new FrameworkPropertyMetadata
    {
        CoerceValueCallback = CoerceCallback,
        DefaultValue = "default value",
        PropertyChangedCallback = ChangedCallback
    });

निष्कर्ष

नियमित और संलग्न निर्भरता गुणों के बीच मुख्य (और केवल) अंतर डिफ़ॉल्ट निर्भरता है जो डिपेंडेंसीप्रोपरेटीडीफॉल्टमाटाटाटा संपत्ति के माध्यम से उपलब्ध है । यह भी टिप्पणी अनुभाग में उल्लेख किया गया है :

गैर-अटैच किए गए गुणों के लिए, इस संपत्ति द्वारा लौटाए गए मेटाडेटा प्रकार को संपत्ति के प्रकार में नहीं जोड़ा जा सकता है , भले ही संपत्ति मूल रूप से व्युत्पन्न मेटाडेटा प्रकार के साथ पंजीकृत हो। यदि आप मूल रूप से पंजीकृत मेटाडेटा को इसके मूल रूप से व्युत्पन्न मेटाडेटा प्रकार सहित चाहते हैं, तो मूल रजिस्टरिंग प्रकार को पैरामीटर के रूप में पास करने के बजाय, गेटमेटाटा (टाइप) को कॉल करें ।

संलग्न गुणों के लिए, इस संपत्ति द्वारा लौटाए गए मेटाडेटा का प्रकार मूल रजिस्टरअटैच्ड पंजीकरण विधि में दिए गए प्रकार से मेल खाएगा ।

प्रदान किए गए कोड में यह स्पष्ट रूप से दिखाई देता है। पंजीकरण पद्धति में छोटे संकेत भी छिपे होते हैं, अर्थात RegisterAttachedमेटाडेटा पैरामीटर के लिए नाम दिया गया है defaultMetadata, जबकि Registerइसके लिए नाम दिया गया है typeMetadata। संलग्न गुणों के लिए प्रदान की गई मेटाडेटा डिफ़ॉल्ट मेटाडेटा बन जाती है। हालांकि, नियमित गुणों के मामले में, डिफ़ॉल्ट मेटाडेटा हमेशा PropertyMetadataकेवल DefaultValueसेट (या तो मेटाडेटा या स्वचालित रूप से) से सेट के साथ एक ताज़ा उदाहरण है । केवल बाद की कॉल OverrideMetadataवास्तव में प्रदान किए गए मेटाडेटा का उपयोग करती है।

परिणाम

मुख्य व्यावहारिक अंतर यह है कि नियमित गुणों के मामले में CoerceValueCallbackऔर मालिक के प्रकार के रूप में घोषित प्रकार से हीPropertyChangedCallback लागू होते हैं , और संलग्न गुणों के लिए वे सभी प्रकार के लिए लागू होते हैं। इस परिदृश्य में:

var d = new DependencyObject();
d.SetValue(SomeClass.SomeProperty, "some value");

पंजीकृत PropertyChangedCallback को बुलाया जाएगा यदि संपत्ति को संलग्न संपत्ति के रूप में पंजीकृत किया गया था, लेकिन यह नहीं कहा जाएगा कि क्या यह एक नियमित संपत्ति के रूप में पंजीकृत था। उसी को जाता है CoerceValueCallback

एक द्वितीयक अंतर इस तथ्य से उपजा है कि OverrideMetadataकिस प्रकार की आपूर्ति की जानी चाहिए DependencyObject। व्यवहार में इसका अर्थ है कि नियमित गुणों के लिए स्वामी प्रकार से व्युत्पन्न होना चाहिएDependencyObject , जबकि संलग्न गुणों के लिए किसी भी प्रकार (स्थैतिक वर्ग, संरचना, enums, प्रतिनिधियों, आदि सहित) हो सकता है।

परिशिष्ट

@ MarqueIV के सुझाव के अलावा, कई मौकों पर मैंने राय दी है कि नियमित और संलग्न गुण XAML में उपयोग किए जाने के तरीके में भिन्न होते हैं । अर्थात्, नियमित गुणों में संलग्न नाम सिंटैक्स की आवश्यकता होती है क्योंकि संलग्न गुणों के लिए आवश्यक स्पष्ट सिंटैक्स का विरोध किया जाता है। यह तकनीकी रूप से सच नहीं है , हालांकि व्यवहार में यह आमतौर पर मामला है। विस्तृत जानकारी के लिए:

<!-- Implicit property name -->
<ns:SomeClass SomeProperty="some value" /> 

<!-- Explicit property name -->
<DependencyObject ns:SomeClass.SomeProperty="some value" />

में शुद्ध XAML , केवल इन वाक्यविन्यास के उपयोग के संचालन नियम निम्नलिखित हैं:

  • इम्प्लिक्ट नाम सिंटैक्स का उपयोग किसी तत्व पर किया जा सकता है यदि और केवल उस वर्ग का जो इस तत्व का प्रतिनिधित्व करता है , उस नाम का सीएलआर गुण है
  • स्पष्ट नाम वाक्य रचना एक तत्व पर इस्तेमाल किया जा सकता यदि और केवल यदि वर्ग पूरा नाम का पहला भाग द्वारा निर्दिष्ट उचित स्थिर को उजागर करता है प्राप्त / सेट विधियों (के रूप में संदर्भित accessors पूरा नाम का दूसरा हिस्सा मिलान नाम के साथ)

इन शर्तों को संतुष्ट करने से आप संबंधित सिंटैक्स का उपयोग करने में सक्षम होते हैं, चाहे बैकिंग निर्भरता संपत्ति को नियमित या संलग्न किया गया हो।

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


71

संलग्न गुण एक प्रकार की निर्भरता संपत्ति हैं। अंतर यह है कि उनका उपयोग कैसे किया जाता है।

संलग्न संपत्ति के साथ, संपत्ति को उस वर्ग पर परिभाषित किया जाता है जो उसी वर्ग के लिए नहीं है जिसके लिए इसका उपयोग किया जा रहा है। यह आमतौर पर लेआउट के लिए उपयोग किया जाता है। अच्छे उदाहरण पैनल हैं ।ZIndex या Grid.Row - आप इसे एक नियंत्रण (यानी: बटन) पर लागू करते हैं, लेकिन यह वास्तव में पैनल या ग्रिड में परिभाषित होता है। संपत्ति बटन के उदाहरण के लिए "संलग्न" है।

यह एक कंटेनर की अनुमति देता है, उदाहरण के लिए, ऐसे गुण बनाने के लिए जो किसी भी UIelement पर उपयोग किए जा सकते हैं।

कार्यान्वयन के अंतर के रूप में - यह मूल रूप से रजिस्टर बनाम रजिस्टरअटैच का उपयोग करने का मामला है जब आप संपत्ति को परिभाषित करते हैं।


10
लेकिन वास्तव में क्या अंतर है ?! मैंने जो देखा है उससे आप एक गैर-अटैच संपत्ति को कोड के माध्यम से दूसरे में संलग्न कर सकते हैं (मुझे लगता है कि यह हालांकि XAML में अवरुद्ध है।) शायद यही अंतर है?
मार्क ए। डोनोहे

5

अटैच किए गए गुण मूल रूप से कंटेनर एलिमेंट्स के लिए होते हैं। जैसे अगर आपके पास ग्रिड है और आपके पास ग्रिड है। ग्रिड में जगह।

निर्भरता की संपत्ति संपत्ति की तरह है जो मूल रूप से किसी अन्य वर्ग की है और इसका उपयोग अन्य वर्ग में किया जाता है। उदाहरण: जैसे आपके पास एक आयत है यहाँ ऊंचाई और चौड़ाई आयत के नियमित गुण हैं, लेकिन बाएँ और ऊपर निर्भरता गुण हैं क्योंकि यह कैनवस वर्ग का है।


-1

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


-1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.