आप अपने .xaml.cs
फ़ाइलों को कक्षाओं अपने संकलित XAML फ़ाइलों का समर्थन कर partial
वर्ग के रूप में चिह्नित कर रहे हैं में देख सकते हैं। एक एक्सएएमएल बिल्ड टास्क .cs
फ़ाइल को दूसरी आंशिक कक्षा अनुभाग के साथ उत्पन्न करता है जिसमें IComponentConnector.InitializeComponent()
विधि का कार्यान्वयन होता है, जिसे कोड के पीछे डिफॉल्ट कन्स्ट्रक्टर द्वारा बुलाया जाता है। यह विधि मूल रूप से एक्सएएमएल (जो वास्तव में इस बिंदु पर बीएएमएल फॉर्म में है) के माध्यम से चलती है और एक्सएएमएल स्रोत से एक नई वस्तु बनाने के विरोध में, नव निर्मित ऑब्जेक्ट को "ठीक करने" के लिए इसका उपयोग करती है, जो होगा यदि आप ऑब्जेक्ट को लोड या पार्स करने के लिए XamlReader
का उपयोग करना था।
तो, जब आप एक नई संकलित XAML ऑब्जेक्ट (उदा।, UserControl
) को तुरंत चालू करते हैं, तो कन्स्ट्रक्टर में InitializeComponent()
पर कॉल से पहले जो कोड पहले से निष्पादित होगा, निष्पादित होगा। फिर, XAML फ़ाइल में सेट सभी गुण और ईवेंट हैंडलर को कॉल के दौरान InitializeComponent()
पर संसाधित किया जाएगा, जिसके बाद कन्स्ट्रक्टर फिर से शुरू होता है। यह जानना उपयोगी हो सकता है, क्योंकि आप यह सुनिश्चित करना चाहते हैं कि XAML फ़ाइल संसाधित होने से पहले या बाद में कुछ गुण सेट हो जाएं।
कैसे XAML पार्स किया गया है के रूप में, यह अनिवार्य रूप से संपत्ति कार्य, वस्तु घोषणाओं, आदि का प्रतिनिधित्व XAML नोड्स, जो System.Xaml
में सेवाओं द्वारा क्रम में प्रदर्शन कर रहे हैं की एक धारा के रूप में पढ़ा जाता है। यह नोड स्ट्रीम एक सामान्य ऑब्जेक्ट मॉडल पर आधारित है, जिसे बीएएमएल स्ट्रीम, एक एक्सएमएल दस्तावेज़ (उदाहरण के लिए, एक ढीला .xaml
फ़ाइल), अन्य ऑब्जेक्ट इंस्टेंस इत्यादि से बनाया गया हो सकता है। बीएएमएल, एक्सएमएल-आधारित प्रारूप से अधिक कॉम्पैक्ट है आम तौर पर पार्स करने के लिए तेज़ है।
परिशिष्ट: उदाहरण आपके द्वारा जोड़े में, आप से पूछना कैसे पार्सर देखता है कि एक Button
वस्तु बनाने की आवश्यकता है और Margin
सेट। संक्षिप्त जवाब है: यह निर्भर करता है। विशेष रूप से, यह XAML स्ट्रीम को पढ़ने के लिए उपयोग किए गए स्कीमा संदर्भ पर निर्भर करता है।
XAML पार्सर अपना अलग प्रकार प्रणाली, जिनमें से कम से कम दो कार्यान्वयन हैं का उपयोग करता है:
- एक मानक CLR प्रकार प्रणाली प्रतिबिंब और
System.ComponentModel
पर आधारित है;
- एक WPF प्रकार प्रणाली है कि निर्भरता गुणों के लिए विशेष सहायता सहित और कराई घटनाओं से # 1 फैली हुई है।
यह XAML भाषा युक्ति की मेरी याद पर आधारित है, लगभग क्या होता है:
- XAML पार्सर
Button
प्रकार, के लिए एक StartObject
नोड का सामना करना पड़ता है जो (मानक WPF नाम स्थान मैपिंग के लिए) System.Windows.Controls.Button
पर हल करता है। यह पार्सर को बताता है कि इसे Button
ऑब्जेक्ट का उदाहरण बनाने की आवश्यकता है, जो प्रतिबिंब के माध्यम से अपने डिफ़ॉल्ट कन्स्ट्रक्टर का आह्वान करके करता है।
- धारा में अगले नोड
Margin
के एक सदस्य के नाम के साथ, एक StartMember
नोड है। WPF स्कीमा संदर्भ के लिए प्रकार मॉडल इसे Margin
निर्भरता संपत्ति पर हल करेगा।
- एक
Value
नोड जो पार्सर बताता "10"
(एक स्ट्रिंग) के मान सेट करने के लिए अगले बात आती है,। पार्सर देखता है कि संपत्ति प्रकार Thickness
स्ट्रिंग मान के साथ असंगत है। यह [ValueSerializer]
विशेषता Margin
संपत्ति पर विशेषता मौजूद है, जिसका उपयोग स्ट्रिंग को कन्वर्ट करने के लिए किया जा सकता है; ऐसी कोई विशेषता मौजूद नहीं है। यह [TypeConverter]
विशेषता के लिए संपत्ति की जांच करता है; फिर, यह कोई नहीं पाता है। यह Thickness
प्रकार पर ही एक [TypeConverter]
विशेषता के लिए लग रहा है और जो निर्देश देता है यह एक ThicknessConverter
उपयोग करने के लिए एक Thickness
में स्ट्रिंग मान परिवर्तित करने के लिए एक पाता है,। ऐसा करता है चूंकि Margin
एक निर्भरता संपत्ति है, इसलिए यह संपत्ति मूल्य निर्धारित करने के लिए SetValue()
API का उपयोग करता है; अगर यह एक सीएलआर संपत्ति थी, तो यह प्रतिबिंब या PropertyDescriptor
का उपयोग करेगा।
- एक
EndMember
नोड पार्सर संपत्ति काम समाप्त करने के लिए कहता है।
- पार्सर सामग्री
"OK"
सामग्री के साथ Value
नोड का सामना करता है। पार्सर जानता है कि यह एक जटिल वस्तु का निर्माण कर रहा है, इसलिए सामग्री पूरी वस्तु का प्रतिनिधित्व नहीं कर सकती है। यह Button
पर [ContentProperty]
विशेषता और इसकी सुपरटिप्प्स की विशेषता है; यह ContentControl
पर एक पाता है, जो इंगित करता है कि मान Content
संपत्ति (जो संबंधित निर्भरता संपत्ति के लिए हल हो जाता है) सेट करने के लिए उपयोग किया जाना चाहिए। Content
एक object
है, इसलिए यह string
मूल्य सीधे (फिर से, SetValue()
का प्रयोग करके) प्रदान करती है।
- अगले नोड
EndObject
जो पार्सर यह प्रसंस्करण Button
वस्तु समाप्त हो गया है बताता है।
ध्यान दें कि मैंने चीजों को सरल बनाने के लिए "पार्सर" शब्द का उपयोग किया था। सच में, इनमें से कोई भी पार्सिंग चरण में नहीं होता है (यदि कोई "पार्सिंग" चरण भी मौजूद है)। "पार्सिंग" चरण के रूप में आप क्या सोच सकते हैं केवल एक्सएएमएल नोड्स की धारा का निर्माण है। घोषित वस्तु (ओं) की सृजन और/या आबादी वास्तव में उस स्ट्रीम को XamlObjectWriter
में खिलाकर होती है, जो कि XamlWriter
का कार्यान्वयन है जो किसी ऑब्जेक्ट को एक्सएएमएल नोड्स (जैसे एक्सएमएल दस्तावेज़ या बीएएमएल स्ट्रीम के विपरीत) लिखता है। उच्च स्तर पर, केवल दो चीजें हो रही हैं:
XamlReader
एक्सएएमएल नोड्स की धारा में कुछ बदलता है।
XamlWriter
एक्सएएमएल नोड्स की एक धारा को कुछ में बदल देता है।
एक compled XAML संसाधन के मामले में, एक संकलन समय निर्माण कार्य पाइप एक BamlWriter
में एक XamlXmlReader
के उत्पादन में XAML "संकलन" करने के लिए।रनटाइम पर, BamlReader
का इनपुट रूट ऑब्जेक्ट बनाने या "ठीक करने" के लिए XamlObjectWriter
में पाइप किया गया है।
एक बार जब आप इसे समझ लेंगे, तो आप एक्सएएमएल को एक शक्तिशाली धारावाहिकता और दृढ़ता प्रारूप के रूप में पहचानना शुरू कर सकते हैं, क्योंकि यूआई बनाने के लिए केवल एक भाषा के विपरीत।
माइक, आपके अच्छे उत्तर के लिए धन्यवाद। आपका परिशिष्ट वह है जो मुझे चाहिए था। इसलिए, डब्ल्यूपीएफ इंजन द्वारा ऑब्जेक्ट ट्री का निर्माण करने से हमारे माइक्रो उदाहरण में प्रतिबिंब का भारी उपयोग होता है - एक बटन ऑब्जेक्ट का निर्माण, यह पता लगाने के लिए कि किस प्रकार का कनवर्टर उपयोग करना है, टाइपकॉन्टर का निर्माण करना, यह पता लगाना कि मार्जिन एक निर्भरता संपत्ति है, आदि। – WpfNewbie
हां, एक्सएएमएल प्रकार प्रणाली में प्रतिबिंब का एक अच्छा सौदा चल रहा है। –
महान उत्तर !! – nawfal