2010-12-09 11 views
5

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

अब उन वर्गों के लिए मुझे दो वीएम कक्षाएं - ग्राहकVM और पताVM बनाने की आवश्यकता है। ग्राहकVM में पताVM ऑब्जेक्ट्स का अवलोकन करने योग्य चयन होना चाहिए। उन वीएम कक्षाओं में किए गए प्रत्येक परिवर्तन (जिसमें ग्राहक सेवा और पताVM दोनों पर सभी सीआरयूडी संचालन शामिल हैं) को मॉडल कक्षाओं में प्रतिबिंबित करने की आवश्यकता है - यही कारण है कि मैं कोड का एक लूट लिखना समाप्त करता हूं। ObservableCollection की बदली हुई घटना की सदस्यता लेता है और यदि कोई नई वस्तु जोड़ दी जाती है तो मॉडल में एक नई वस्तु जोड़ें ... और इसी तरह ...

इसके साथ क्या करना है? एमवीवीएम का उपयोग करते समय यह सामान्य है? क्या मैं सब ठीक कर रहा हूँ? इस तरह के एक साधारण वर्ग पदानुक्रम के लिए आवश्यक कोड की मात्रा कैसे कटौती करें? क्या कोई ढांचा है जो मूल वीएम कक्षाएं बना सकता है जो पदानुक्रम में अन्य वर्गों के साथ "अच्छा व्यवहार" करता है? कक्षा संबंधों को और अधिक जटिल होने पर क्या करना है?

या इसे सरल रखने के लिए:

कैसे मॉडल संग्रह में वीएम संग्रह में किया बदलाव को प्रतिबिंबित करने के लिए: वहाँ भी एक ही है

Customer1.Adresses.Add(new Address{City="New York"}) 

:

CustomerVM1.AdressesVM.Add(new AddressVM{City="New York"}) 

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

उत्तर

0

आप मेरे मॉडल में एक सादे-पुराने संग्रह के साथ मेरे व्यूमोडेल सिंक में ObservableCollection को कैसे बनाए रखने के तरीके को समझने की कोशिश करते समय ठीक उसी समस्या में भाग रहे हैं। एक ObservableCollection अद्भुत है क्योंकि दृश्य इसे बाध्य कर सकता है और जब संग्रह बदलता है तो स्वचालित रूप से बदल जाता है। दुर्भाग्यवश आपने सिंक की समस्या को एक स्तर से नीचे ले जाया है।

एक विकल्प मॉडल में भी हर जगह पर्यवेक्षण चयन का उपयोग करना है। यह बहुत साफ वास्तुकला नहीं है क्योंकि एमवीवीएम मॉडल पर कोई मांग नहीं करना चाहता है।

क्या मैं हल करने के लिए यह एक प्रस्तुतकर्ता लागू करने के लिए था, इसलिए मेरी वास्तुकला इस तरह दिखता किया: इसके अलावा

View -> ViewModel <-> Presenter <-> Model 

, मैं अपने ViewModels गूंगा बनाया है।

  1. उपयोगकर्ता क्लिक करता जोड़ें बटन
  2. ViewModel या तो एक घटना है कि प्रस्तुतकर्ता का सदस्य बनता जन्म देती है, या प्रस्तोता पर एक प्रणाली को बुलाती है, या सिर्फ एक कॉल: यहां बताया किसी आम उपयोगकर्ता कार्रवाई पूरा करने दीक्षा से होता है है जब कॉलमोडेल का निर्माण किया गया था तब प्रस्तुतकर्ता ने व्यूमोडेल को प्रदान किया था। अनिवार्य रूप से यह प्रस्तुतकर्ता को कार्रवाई का प्रतिनिधित्व करता है।
  3. प्रेजेंटर कॉल मॉडल पर जोड़ें।
  4. मॉडल ऐड कॉल पर प्रतिक्रिया करता है, जिसमें सादे-पुराने संग्रह सहित इसके सभी प्रासंगिक राज्य को अद्यतन किया जाता है।
  5. प्रस्तुतकर्ता, मॉडल पर कार्रवाई निष्पादित करने के बाद, मॉडल से नए राज्य को पढ़ता है और राज्य को ViewModel में लिखता है। बाध्यकारी दृश्य को सिंक्रनाइज़ करने का ख्याल रखता है।

तो आपके मामले में, प्रस्तुतकर्ता एक CollectionChanged घटना के लिए ViewModel में ObservableCollection पर सदस्यता सकता है, और जब यह बदलता है, यह बुला मॉडल पर जोड़े द्वारा घटना के लिए प्रतिक्रिया करते हैं। दूसरी तरफ, जब प्रेजेंटर कुछ अन्य उपयोगकर्ता क्रियाओं को संसाधित कर रहा है जो मॉडल पर जोड़ें (यह जानता है क्योंकि यह सभी मॉडल के साथ बातचीत को संभालता है), तो यह जानता है कि इसे ObservableCollection में उस परिवर्तन को प्रचारित करना है ViewModel।

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

+0

एक महान उत्तर के लिए बहुत बहुत धन्यवाद। यह निश्चित रूप से समस्या को हल करने का एक तरीका है, लेकिन आईएमओ जो वास्तव में आपको कम कोड नहीं लिखता है - यह करने के लिए यह क्लीनर तरीका है। फिर भी आपको प्रेजेंटर की आवश्यकता है जो एक और परत है और चीजें जितनी जटिल हो सकती हैं उससे ज्यादा जटिल होती हैं। – kubal5003

+0

कल मैं वीएम कक्षाओं के निर्माण के बजाय "कम" एमवीवीएम की तरह sth करने की सोच रहा था, मैं आंशिक कक्षाओं के उपयोग के माध्यम से मॉडल वर्ग का विस्तार करना चाहता हूं। अब मुझे जिस संपत्ति की आवश्यकता है, उसके लिए मैं एक और बना सकता हूं जो पुराने को encapsulates - जैसा कि एमवीवीएम में है। एक सादे पुराने संग्रह के लिए मैं केवल एक रैपर संग्रह बना सकता हूं जो INotifyCollectionChanged लागू करता है और भंडारण के लिए सादे पुराने संग्रह का उपयोग करता है। आपने इस बारे में क्या सोचा? – kubal5003

+0

एक और चीज जिसे मैं सोच रहा था शायद माईकोलेक्शन <वीएमसीएलएएस, एमसीएलएएस> -> जैसे सामान्य संग्रह बनाना है, यह मॉडल <-> व्यूमोडेल इंटरैक्शन के बारे में आवश्यक सब कुछ जानना चाहिए और प्रस्तुतकर्ता में जो कुछ भी आप करते हैं उसे संभालने में सक्षम होना चाहिए। अगर अच्छी तरह से लिखा जाता है तो इसे हर जगह पुन: उपयोग किया जा सकता है। – kubal5003

1

आप WPF Application Framework (WAF) की BookLibrary नमूना आवेदन में रुचि हो सकती। यह दिखाता है कि एंटिटी फ्रेमवर्क और एमवीवीएम का एक साथ उपयोग कैसे करें।

संक्षिप्त संकेत: यह प्रत्येक इकाई वर्ग के लिए एक रैपर व्यूमोडेल नहीं बनाता है। इसके बजाय, यह दृश्यों के लिए ViewModel कक्षाएं बनाता है।

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