WPF में (कस्टम) निर्भरता संपत्ति और संलग्न संपत्ति के बीच अंतर क्या है? प्रत्येक के लिए उपयोग क्या हैं? आमतौर पर कार्यान्वयन कैसे भिन्न होते हैं?
जवाबों:
चूंकि मुझे इस मामले पर कोई दस्तावेज नहीं मिला, इसलिए स्रोत कोड के आसपास कुछ प्रहार हुआ , लेकिन यहां एक जवाब है।
एक नियमित रूप से और एक संलग्न संपत्ति के रूप में एक निर्भरता संपत्ति को पंजीकृत करने के बीच एक अंतर है, एक "दार्शनिक" एक के अलावा ( नियमित गुणों को घोषित प्रकार और इसके व्युत्पन्न प्रकारों द्वारा उपयोग किए जाने का इरादा है, संलग्न गुणों का उपयोग करने का इरादा है। मनमाना 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 , केवल इन वाक्यविन्यास के उपयोग के संचालन नियम निम्नलिखित हैं:
इन शर्तों को संतुष्ट करने से आप संबंधित सिंटैक्स का उपयोग करने में सक्षम होते हैं, चाहे बैकिंग निर्भरता संपत्ति को नियमित या संलग्न किया गया हो।
अब उल्लिखित गलत धारणा इस तथ्य के कारण है कि अधिकांश ट्यूटोरियल (स्टॉक विजुअल स्टूडियो कोड स्निपेट्स के साथ) आपको नियमित निर्भरता गुणों के लिए सीएलआर संपत्ति का उपयोग करने , और संलग्न लोगों के लिए एक्सेस सेट करने का निर्देश देते हैं। लेकिन एक ही समय में दोनों का उपयोग करने से आपको कुछ भी नहीं रोक सकता है, जिससे आप अपने पसंदीदा सिंटैक्स का उपयोग कर सकते हैं।
संलग्न गुण एक प्रकार की निर्भरता संपत्ति हैं। अंतर यह है कि उनका उपयोग कैसे किया जाता है।
संलग्न संपत्ति के साथ, संपत्ति को उस वर्ग पर परिभाषित किया जाता है जो उसी वर्ग के लिए नहीं है जिसके लिए इसका उपयोग किया जा रहा है। यह आमतौर पर लेआउट के लिए उपयोग किया जाता है। अच्छे उदाहरण पैनल हैं ।ZIndex या Grid.Row - आप इसे एक नियंत्रण (यानी: बटन) पर लागू करते हैं, लेकिन यह वास्तव में पैनल या ग्रिड में परिभाषित होता है। संपत्ति बटन के उदाहरण के लिए "संलग्न" है।
यह एक कंटेनर की अनुमति देता है, उदाहरण के लिए, ऐसे गुण बनाने के लिए जो किसी भी UIelement पर उपयोग किए जा सकते हैं।
कार्यान्वयन के अंतर के रूप में - यह मूल रूप से रजिस्टर बनाम रजिस्टरअटैच का उपयोग करने का मामला है जब आप संपत्ति को परिभाषित करते हैं।
अटैच किए गए गुण मूल रूप से कंटेनर एलिमेंट्स के लिए होते हैं। जैसे अगर आपके पास ग्रिड है और आपके पास ग्रिड है। ग्रिड में जगह।
निर्भरता की संपत्ति संपत्ति की तरह है जो मूल रूप से किसी अन्य वर्ग की है और इसका उपयोग अन्य वर्ग में किया जाता है। उदाहरण: जैसे आपके पास एक आयत है यहाँ ऊंचाई और चौड़ाई आयत के नियमित गुण हैं, लेकिन बाएँ और ऊपर निर्भरता गुण हैं क्योंकि यह कैनवस वर्ग का है।
संलग्न गुण एक विशेष प्रकार की DependencyProperties हैं। वे आपको एक ऐसी वस्तु के लिए एक मूल्य संलग्न करने की अनुमति देते हैं जो इस मूल्य के बारे में कुछ भी नहीं जानता है। इस अवधारणा के लिए एक अच्छा उदाहरण लेआउट पैनल हैं। प्रत्येक लेआउट पैनल को अपने बाल तत्वों को संरेखित करने के लिए अलग-अलग डेटा की आवश्यकता होती है। कैनवस को टॉप और लेफ्ट की जरूरत है, डॉकपेन को डॉक आदि की जरूरत है, क्योंकि आप अपना खुद का लेआउट पैनल लिख सकते हैं, लिस्ट अनंत है। तो आप देखते हैं, सभी WPF नियंत्रणों पर उन सभी गुणों को रखना संभव नहीं है। समाधान संलग्न गुण हैं। वे उस नियंत्रण द्वारा परिभाषित होते हैं, जिसे किसी विशिष्ट संदर्भ में दूसरे नियंत्रण से डेटा की आवश्यकता होती है। उदाहरण के लिए एक तत्व जो कि पेरेंट लेआउट पैनल द्वारा संरेखित किया जाता है।
मुझे लगता है कि आप कक्षा में संलग्न संपत्ति को परिभाषित कर सकते हैं या आप इसे किसी अन्य कक्षा में परिभाषित कर सकते हैं। हम हमेशा मानक Microsoft नियंत्रणों का विस्तार करने के लिए संलग्न संपत्ति का उपयोग कर सकते हैं। लेकिन निर्भरता संपत्ति, आप इसे अपने स्वयं के कस्टम नियंत्रण में परिभाषित करते हैं। उदा। आप एक मानक नियंत्रण से अपना नियंत्रण प्राप्त कर सकते हैं, और अपने स्वयं के नियंत्रण में एक निर्भरता संपत्ति को परिभाषित कर सकते हैं और इसका उपयोग कर सकते हैं। यह संलग्न संपत्ति को परिभाषित करने के बराबर है, और मानक नियंत्रण में इस संलग्न संपत्ति का उपयोग करें।