2011-08-31 19 views
26

प्रश्न Linking DataContext with another property in WPF की निरंतरता के रूप में।डेटाकॉन्टेक्स्ट के लिए क्या है?

अनुसंधान के बहुत अंत में मैं बहुत पता लगाने के लिए हैरान था कि जब एक ऐसा ही कुछ लिखते हैं:

<Label Content="{Binding Path=Name}" /> 

DataContext जिसके खिलाफ Content संपत्ति आबद्ध है Label नियंत्रण ही की है! तथ्य यह है कि यह अभी भी काम करता है निकटतम माता-पिता से DataContext मान की डिफ़ॉल्ट विरासत के कारण है।

लेकिन अगर आप इस लेबल एक कस्टम नियंत्रण में लिपटे है, और आपको लगता है कि नियंत्रण से DataContext संपत्ति के लिए अपने डेटा के लिए बाध्य नहीं करना चाहते, तो आप और अधिक संभावना प्यार के लिए होगा:

<Controls:SearchSettings Settings="{Binding Path=Settings}" /> 

और आप यहाँ हैं। के लिए Label के लिए के लिए DataContext के रूप में DataContext के रूप में Settings सेट करने की आवश्यकता है, लेकिन आप नहीं कर सकते हैं, क्योंकि इससे Settings संपत्ति का पुन: बाध्यकारी ट्रिगर होगा।

मैं विभिन्न स्रोतों का उपयोग कर बाध्यकारी गुण मिश्रण में समझ में नहीं आता: DataContext, ElementName द्वारा, आदि तो क्यों मैं कभी DataContext का प्रयोग करेंगे?

उत्तर

78

जब आप लिखना

<Label name="myLabel" Content="{Binding Path=Name}" /> 

आप myLabel.DataContext.Name के लिए बाध्य कर रहे हैं, और myLabel.Name नहीं।

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


तो मान लीजिए आप एक खिड़की है। DataContext को सेट किए बिना, विंडो अभी भी प्रदर्शित होती है लेकिन इसके पीछे कोई डेटा नहीं है।

अब myWindow.DataContext = new ClassA(); सेट करने का अनुमान है। अब खिड़की प्रदर्शित करने वाला डेटा ClassA है।यदि ClassA में Name नामक एक संपत्ति है, तो मैं एक लेबल लिख सकता हूं और इसे Name (जैसे आपका उदाहरण) से जोड़ सकता हूं, और ClassA.Name में जो भी मूल्य संग्रहीत किया जाता है, प्रदर्शित होगा।

अब मान लीजिए ClassA की ClassB की संपत्ति है और दोनों वर्गों में Name नामक एक संपत्ति है। यहाँ XAML के एक ब्लॉक जो DataContext करने के उद्देश्य को दिखाता है, और कैसे एक नियंत्रण अपने आप DataContext

<Window x:Name="myWindow"> <!-- DataContext is set to ClassA --> 
    <StackPanel> <!-- DataContext is set to ClassA --> 

     <!-- DataContext is set to ClassA, so will display ClassA.Name --> 
     <Label Content="{Binding Name}" /> 

     <!-- DataContext is still ClassA, however we are setting it to ClassA.ClassB --> 
     <StackPanel DataContext="{Binding ClassB}"> 

      <!-- DataContext is set to ClassB, so will display ClassB.Name --> 
      <Label Content="{Binding Name}" /> 

      <!-- DataContext is still ClassB, but we are binding to the Window's DataContext.Name which is ClassA.Name --> 
      <Label Content="{Binding ElementName=myWindow, Path=DataContext.Name}" /> 
     </StackPanel> 
    </StackPanel> 
</Window> 

आप देख सकते हैं में नहीं एक संपत्ति को उल्लेख करता है का एक उदाहरण है, DataContext जो कुछ आंकड़ों पर आधारित है यूआई ऑब्जेक्ट के पीछे है।

अद्यतन: मैं नए WPF उन है कि मैं अपने ब्लॉग पर एक पोस्ट में इस सवाल का जवाब विस्तार से इतनी बार इस सवाल देखें: What is this “DataContext” you speak of?

+0

हाय! विस्तृत उत्तर के लिए धन्यवाद। परंतु। जो मैं आपको पसंद नहीं करता उदाहरण यह है कि आप DataContext प्रॉपर्टी को बाध्य करते हैं। शायद मैं आपके उदाहरण में स्टैकपैनल को एक अलग नियंत्रण में निकाल दूंगा। यह समझ में आता है कि यदि डेटाकॉन्टेक्स्ट अपने माता-पिता के डेटाकॉन्टेक्स्ट का अलग-अलग हिस्सा है, है ना? और फिर मैं अपने उपयोगकर्ता नियंत्रण की डेटाकॉन्टेक्स्ट संपत्ति को बाध्य नहीं करता, बल्कि स्वयं-वर्णनात्मक नाम के साथ एक विशेष संपत्ति होगी। (मेरा मतलब है कि किसी विशेष नियंत्रण के लिए डेटा कॉन्टेक्स्ट क्या है? मुझे क्या पास करना चाहिए?) और यह चीजें जटिल हो गई हैं। [जारी रखने के लिए] –

+0

जैसा कि मैं डेटाकॉन्टेक्स्ट संपत्ति को बाध्य नहीं करता, इसे मूल नियंत्रण से लिया जाएगा। जिसका अर्थ है कि मैं डेटाकॉन्टेक्स्ट के खिलाफ अपने कस्टम नियंत्रण में नियंत्रण को बाध्य करने में सक्षम नहीं हूं, सिर्फ इसलिए कि मुझे नहीं पता कि वहां क्या है (नियंत्रण नियंत्रित नहीं कर सकता कि इसका बच्चा कौन होगा, और डेटाकॉन्टेक्स्ट इसे प्राप्त करेगा)। समाधान डेटाकॉन्टेक्स्ट को अंदर से नियंत्रित करने के लिए सेट किया जा सकता है (उस विशेष संपत्ति से मूल्य का उपयोग करके)। [जारी रखने के लिए] –

+0

लेकिन यह आपके नियंत्रण की बाध्यकारीता को तोड़ देगा, क्योंकि, जैसा कि आपने बताया है, 'Content = {बाइंडिंग नाम}' लिखा है, 'लेबल' डेटाकॉन्टेक्स्टनाम 'से जुड़ा हुआ है और लेबल' माता-पिता 'से नहीं है। DataContext.Name' जैसा कि मैं इसे करने की उम्मीद करता हूं। –

1

कि विशेष मामले में, तुम कर सकते हो:

<Controls:SearchSettings DataContext="{Binding Path=Settings}" Settings="{Binding}" /> 

मान लिया जाये कि आप सब कुछ है कि के रूप में यह डेटा संदर्भ की सेटिंग का उपयोग करने के लिए SearchSettings की सामग्री हो सकती है चाहता हूँ। असल में, डेटाकॉन्टेक्स्ट तत्व को स्वयं किसी भी वंश को प्रभावित करता है जो इसे स्पष्ट रूप से ओवरराइड नहीं करता है।

0

ज्यादातर मामलों में आप आइटम्सकंट्रोल पर कुछ टेम्पलेट्स में डेटाकॉन्टेक्स्ट से जुड़ना चाहते हैं, उदाहरण के लिए वर्तमान में टेम्पलेट किए गए आइटम से जुड़ने का यही एकमात्र तरीका है। DataContext के लिए आगे की बाइंडिंग लिखने और पढ़ने के लिए अच्छी हैं क्योंकि वे संक्षिप्त हैं।

अपने उदाहरण में आप अभी भी DataContext सेट कर सकते हैं, आप केवल क्रमश सेटिंग्स पर बाध्यकारी संशोधित करने की आवश्यकता:

<Controls:SearchSettings DataContext="{Binding Settings}" Settings="{Binding}"/> 
+0

मैं इस दृष्टिकोण के बारे में सोचा है, लेकिन यह मतलब नहीं है। अगर मुझे केवल एक की ज़रूरत है, तो मुझे दो गुणों को क्यों बांधना चाहिए? –

+0

@EugeneStrizhok: आपको केवल एक की आवश्यकता नहीं है, यह आपको स्रोत सेट किए बिना बाल नियंत्रण में सेटिंग्स से जुड़ने की अनुमति देता है क्योंकि अब आप DataContext का उपयोग कर सकते हैं। –

1

CodeProject से किशोर Gaddam द्वारा:

DataContext एक है डेटा बाइंडिंग में सबसे मौलिक अवधारणाओं में से। बाइंडिंग ऑब्जेक्ट को कहीं से अपना डेटा प्राप्त करने की आवश्यकता है, और डेटा के स्रोत को निर्दिष्ट करने के कुछ तरीके हैं जैसे कि सीधे बाध्यकारी में स्रोत प्रॉपर्टी का उपयोग करना, पेड़ में घुसते समय निकटतम तत्व से DataContext को विरासत में रखना, ElementName सेट करना और बाइंडिंग ऑब्जेक्ट में RelativeSource गुण।

CodeProject पर विस्तृत उदाहरण: http://www.codeproject.com/Articles/321899/DataContext-in-WPF

संबंधित मुद्दे