2013-12-11 8 views
16

एक्सएएमएल (या बीएएमएल) लोड करने और रूट ऑब्जेक्ट (विंडो, उदाहरण के लिए) प्राप्त करने के बीच आंतरिक रूप से क्या होता है?एक्सएएमएल कैसे रनटाइम पर व्याख्या और निष्पादित किया जाता है?

मेरे दिमाग में सबसे पहले क्या पॉप अप होता है यह है कि प्रतिबिंब का उपयोग वस्तुओं को बनाने, अपनी गुणों को सेट करने के लिए किया जाता है। लेकिन शायद मैं गलत हूँ?

शायद कोई यह बता सकता है कि एक्सएएमएल/बीएएमएल को रनटाइम पर कैसे पार्स किया गया है और निष्पादित किया गया है या स्पष्टीकरण के साथ एक अच्छे लेख का लिंक दिया है?

थोड़ा और अधिक स्पष्ट मेरे सवाल करने के लिए, की लघु उदाहरण पर चर्चा करते हैं:

<Button Margin="10">OK</Button> 

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

उत्तर

25

आप अपने .xaml.cs फ़ाइलों को कक्षाओं अपने संकलित XAML फ़ाइलों का समर्थन कर partial वर्ग के रूप में चिह्नित कर रहे हैं में देख सकते हैं। एक एक्सएएमएल बिल्ड टास्क .cs फ़ाइल को दूसरी आंशिक कक्षा अनुभाग के साथ उत्पन्न करता है जिसमें IComponentConnector.InitializeComponent() विधि का कार्यान्वयन होता है, जिसे कोड के पीछे डिफॉल्ट कन्स्ट्रक्टर द्वारा बुलाया जाता है। यह विधि मूल रूप से एक्सएएमएल (जो वास्तव में इस बिंदु पर बीएएमएल फॉर्म में है) के माध्यम से चलती है और एक्सएएमएल स्रोत से एक नई वस्तु बनाने के विरोध में, नव निर्मित ऑब्जेक्ट को "ठीक करने" के लिए इसका उपयोग करती है, जो होगा यदि आप ऑब्जेक्ट को लोड या पार्स करने के लिए XamlReader का उपयोग करना था।

तो, जब आप एक नई संकलित XAML ऑब्जेक्ट (उदा।, UserControl) को तुरंत चालू करते हैं, तो कन्स्ट्रक्टर में InitializeComponent() पर कॉल से पहले जो कोड पहले से निष्पादित होगा, निष्पादित होगा। फिर, XAML फ़ाइल में सेट सभी गुण और ईवेंट हैंडलर को कॉल के दौरान InitializeComponent() पर संसाधित किया जाएगा, जिसके बाद कन्स्ट्रक्टर फिर से शुरू होता है। यह जानना उपयोगी हो सकता है, क्योंकि आप यह सुनिश्चित करना चाहते हैं कि XAML फ़ाइल संसाधित होने से पहले या बाद में कुछ गुण सेट हो जाएं।

कैसे XAML पार्स किया गया है के रूप में, यह अनिवार्य रूप से संपत्ति कार्य, वस्तु घोषणाओं, आदि का प्रतिनिधित्व XAML नोड्स, जो System.Xaml में सेवाओं द्वारा क्रम में प्रदर्शन कर रहे हैं की एक धारा के रूप में पढ़ा जाता है। यह नोड स्ट्रीम एक सामान्य ऑब्जेक्ट मॉडल पर आधारित है, जिसे बीएएमएल स्ट्रीम, एक एक्सएमएल दस्तावेज़ (उदाहरण के लिए, एक ढीला .xaml फ़ाइल), अन्य ऑब्जेक्ट इंस्टेंस इत्यादि से बनाया गया हो सकता है। बीएएमएल, एक्सएमएल-आधारित प्रारूप से अधिक कॉम्पैक्ट है आम तौर पर पार्स करने के लिए तेज़ है।


परिशिष्ट: उदाहरण आपके द्वारा जोड़े में, आप से पूछना कैसे पार्सर देखता है कि एक Button वस्तु बनाने की आवश्यकता है और Margin सेट। संक्षिप्त जवाब है: यह निर्भर करता है। विशेष रूप से, यह XAML स्ट्रीम को पढ़ने के लिए उपयोग किए गए स्कीमा संदर्भ पर निर्भर करता है।

XAML पार्सर अपना अलग प्रकार प्रणाली, जिनमें से कम से कम दो कार्यान्वयन हैं का उपयोग करता है:

  1. एक मानक CLR प्रकार प्रणाली प्रतिबिंब और System.ComponentModel पर आधारित है;
  2. एक WPF प्रकार प्रणाली है कि निर्भरता गुणों के लिए विशेष सहायता सहित और कराई घटनाओं से # 1 फैली हुई है।

यह XAML भाषा युक्ति की मेरी याद पर आधारित है, लगभग क्या होता है:

  1. XAML पार्सर Button प्रकार, के लिए एक StartObject नोड का सामना करना पड़ता है जो (मानक WPF नाम स्थान मैपिंग के लिए) System.Windows.Controls.Button पर हल करता है। यह पार्सर को बताता है कि इसे Button ऑब्जेक्ट का उदाहरण बनाने की आवश्यकता है, जो प्रतिबिंब के माध्यम से अपने डिफ़ॉल्ट कन्स्ट्रक्टर का आह्वान करके करता है।
  2. धारा में अगले नोड Margin के एक सदस्य के नाम के साथ, एक StartMember नोड है। WPF स्कीमा संदर्भ के लिए प्रकार मॉडल इसे Margin निर्भरता संपत्ति पर हल करेगा।
  3. एक Value नोड जो पार्सर बताता "10" (एक स्ट्रिंग) के मान सेट करने के लिए अगले बात आती है,। पार्सर देखता है कि संपत्ति प्रकार Thickness स्ट्रिंग मान के साथ असंगत है। यह [ValueSerializer] विशेषता Margin संपत्ति पर विशेषता मौजूद है, जिसका उपयोग स्ट्रिंग को कन्वर्ट करने के लिए किया जा सकता है; ऐसी कोई विशेषता मौजूद नहीं है। यह [TypeConverter] विशेषता के लिए संपत्ति की जांच करता है; फिर, यह कोई नहीं पाता है। यह Thickness प्रकार पर ही एक [TypeConverter] विशेषता के लिए लग रहा है और जो निर्देश देता है यह एक ThicknessConverter उपयोग करने के लिए एक Thickness में स्ट्रिंग मान परिवर्तित करने के लिए एक पाता है,। ऐसा करता है चूंकि Margin एक निर्भरता संपत्ति है, इसलिए यह संपत्ति मूल्य निर्धारित करने के लिए SetValue() API का उपयोग करता है; अगर यह एक सीएलआर संपत्ति थी, तो यह प्रतिबिंब या PropertyDescriptor का उपयोग करेगा।
  4. एक EndMember नोड पार्सर संपत्ति काम समाप्त करने के लिए कहता है।
  5. पार्सर सामग्री "OK" सामग्री के साथ Value नोड का सामना करता है। पार्सर जानता है कि यह एक जटिल वस्तु का निर्माण कर रहा है, इसलिए सामग्री पूरी वस्तु का प्रतिनिधित्व नहीं कर सकती है। यह Button पर [ContentProperty] विशेषता और इसकी सुपरटिप्प्स की विशेषता है; यह ContentControl पर एक पाता है, जो इंगित करता है कि मान Content संपत्ति (जो संबंधित निर्भरता संपत्ति के लिए हल हो जाता है) सेट करने के लिए उपयोग किया जाना चाहिए। Content एक object है, इसलिए यह string मूल्य सीधे (फिर से, SetValue() का प्रयोग करके) प्रदान करती है।
  6. अगले नोड EndObject जो पार्सर यह प्रसंस्करण Button वस्तु समाप्त हो गया है बताता है।

ध्यान दें कि मैंने चीजों को सरल बनाने के लिए "पार्सर" शब्द का उपयोग किया था। सच में, इनमें से कोई भी पार्सिंग चरण में नहीं होता है (यदि कोई "पार्सिंग" चरण भी मौजूद है)। "पार्सिंग" चरण के रूप में आप क्या सोच सकते हैं केवल एक्सएएमएल नोड्स की धारा का निर्माण है। घोषित वस्तु (ओं) की सृजन और/या आबादी वास्तव में उस स्ट्रीम को XamlObjectWriter में खिलाकर होती है, जो कि XamlWriter का कार्यान्वयन है जो किसी ऑब्जेक्ट को एक्सएएमएल नोड्स (जैसे एक्सएमएल दस्तावेज़ या बीएएमएल स्ट्रीम के विपरीत) लिखता है। उच्च स्तर पर, केवल दो चीजें हो रही हैं:

  1. XamlReader एक्सएएमएल नोड्स की धारा में कुछ बदलता है।
  2. XamlWriter एक्सएएमएल नोड्स की एक धारा को कुछ में बदल देता है।

एक compled XAML संसाधन के मामले में, एक संकलन समय निर्माण कार्य पाइप एक BamlWriter में एक XamlXmlReader के उत्पादन में XAML "संकलन" करने के लिए।रनटाइम पर, BamlReader का इनपुट रूट ऑब्जेक्ट बनाने या "ठीक करने" के लिए XamlObjectWriter में पाइप किया गया है।

एक बार जब आप इसे समझ लेंगे, तो आप एक्सएएमएल को एक शक्तिशाली धारावाहिकता और दृढ़ता प्रारूप के रूप में पहचानना शुरू कर सकते हैं, क्योंकि यूआई बनाने के लिए केवल एक भाषा के विपरीत।

+0

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

+1

हां, एक्सएएमएल प्रकार प्रणाली में प्रतिबिंब का एक अच्छा सौदा चल रहा है। –

+0

महान उत्तर !! – nawfal

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

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