2009-11-25 11 views
14

मेरे पास एक उपयोगकर्ता नियंत्रण है जिसमें कई अन्य उपयोगकर्ता नियंत्रण शामिल हैं। मैं एमवीवीएम का उपयोग कर रहा हूँ। प्रत्येक उपयोगकर्ता नियंत्रण में एक संबंधित वीएम होता है। ये उपयोगकर्ता नियंत्रण एक दूसरे को जानकारी कैसे भेजते हैं? मैं पीछे xaml कोड में किसी भी कोड लिखने से बचना चाहता हूँ। विशेष रूप से मुझे इस बात में रूचि है कि नियंत्रण (मुख्य उपयोगकर्ता नियंत्रण के अंदर) एक-दूसरे से कैसे बात करेंगे और वे कंटेनर उपयोगकर्ता नियंत्रण से कैसे बात करेंगे।एमवीवीएम - उपयोगकर्ता नियंत्रण के लिए एक दूसरे से बात करने का आदर्श तरीका

EDIT: मुझे पता है कि घटनाओं-प्रतिनिधियों का उपयोग करने से मुझे इस समस्या को हल करने में मदद मिलेगी। लेकिन, मैं xaml कोड-पीछे में किसी भी कोड को लिखने से बचना चाहता हूं।

उत्तर

1

मुझे लगता है कि सबसे अच्छा समाधान प्रकाशक/सब्सक्राइबर पैटर्न का उपयोग करेगा। प्रत्येक नियंत्रण कुछ घटनाओं को पंजीकृत करता है और अन्य नियंत्रणों से अवगत घटनाओं को हटा देता है।

घटनाओं का पर्दाफाश करने और उन्हें संलग्न करने के लिए आपको किसी प्रकार की मध्यस्थ/ईवेंट ब्रोकर सेवा का उपयोग करने की आवश्यकता होगी। मुझे एक अच्छा उदाहरण मिला here

+0

क्या आप इसे विस्तार से समझा सकते हैं? क्या आप सीएलआर प्रतिनिधि और घटनाओं का उपयोग कर मतलब है? – Sandbox

+0

मैंने अभी अपना जवाब संपादित किया है जिसमें प्रस्तुति के लिंक को मार्लन ग्रीक के ब्लॉग से उदाहरण कोड के साथ जोड़ा गया है। मॉडलों को प्रकाशक/ग्राहक पैटर्न में संवाद करें (पीछे कोई कोड आवश्यक नहीं है)। मध्यस्थ सेवा ईवेंट हैंडलर पंजीकृत करने के लिए सीएलआर प्रतिनिधियों का उपयोग करती है। – PanJanek

1

मेरी राय में ऐसा करने का सबसे अच्छा तरीका कमांडिंग (रूटेड कमांड/रिले कॉमांड, आदि) के माध्यम से है।

मैं xaml कोड में किसी भी कोड को लिखने से बचना चाहता हूं।

हालांकि यह एक प्रशंसनीय लक्ष्य है, आपको इसके लिए कुछ व्यावहारिकता लागू करनी है, इसे "आप नहीं" नियम के रूप में 100% लागू नहीं किया जाना चाहिए।

+0

http://codebetter.com/blogs/glenn.block/archive/2009/08/02/the-spirit-of-mvvm-viewmodel-it-s-not-a-code-counting-exercise.aspx –

+0

ग्रेट ग्रेट पोस्ट, मुझे इसे पढ़ना होगा! –

0

आप तत्व बाध्यकारी का उपयोग कर यूआई पर तत्वों के बीच संवाद कर सकते हैं, इसलिए आपके द्वारा बनाए गए उपयोगकर्ता नियंत्रण को एक संपत्ति का खुलासा करते हुए, अन्य उपयोगकर्ता नियंत्रण इससे जुड़ सकते हैं। आप मूलभूत गुणों/कार्यान्वयन के बजाय बाध्यकारी, उपयोग निर्भरता गुणों को कॉन्फ़िगर कर सकते हैं IotifyPropertyChanged लेकिन यह सिद्धांत रूप में संभव है, लेकिन इस तरह से संचार करने में सक्षम होने के लिए कुछ पूर्व विचारों की आवश्यकता होती है।

आपको शुद्ध घोषणात्मक तरीके से प्रयास करने के बजाय घटनाओं, कोड और गुणों के संयोजन का उपयोग करके इसे कहीं अधिक आसान लगेगा, लेकिन सिद्धांत में संभव है।

14

आम तौर पर, भागों के बीच संचार की मात्रा को कम करने का प्रयास करना सबसे अच्छा है, क्योंकि हर बार दो उपयोगकर्ता एक-दूसरे से "बात" करते हैं, आप उनके बीच निर्भरता पेश कर रहे हैं।

कहा जा रहा है, वहाँ चीजों की एक जोड़ी पर विचार कर रहे हैं:

  • UserControls हमेशा गुण को उजागर और DataBinding का उपयोग कर के माध्यम से अपने युक्त नियंत्रण करने के लिए "बात" कर सकते हैं। यह बहुत अच्छा है, क्योंकि यह सभी पहलुओं में एमवीवीएम शैली को संरक्षित करता है।
  • युक्त नियंत्रण गुण का उपयोग कर सकते करने के लिए "लिंक" उपयोगकर्ता दो पर दो गुण एक साथ नियंत्रित करता है, फिर से, स्वच्छ सीमाओं

संरक्षण आप अधिक स्पष्ट संचार की आवश्यकता है, तो वहाँ दो मुख्य दृष्टिकोणों हैं।

  1. दोनों तत्वों के लिए एक सेवा को लागू करें, और रनटाइम पर कार्यान्वयन प्रदान करने के लिए निर्भरता इंजेक्शन का उपयोग करें। यह नियंत्रण को सेवा से बात करने देता है, जो बदले में नियंत्रण को सिंक्रनाइज़ कर सकता है, लेकिन निर्भरता को न्यूनतम तक भी रखता है।
  2. नियंत्रण के बीच संदेशों को पारित करने के लिए संदेश के कुछ रूपों का उपयोग करें।कई एमवीवीएम ढांचे इस दृष्टिकोण को लेते हैं, क्योंकि यह संदेश प्राप्त करने से संदेश भेजने को रद्द करता है, फिर से निर्भरता को कम से कम रखता है।
+3

बिंदु 2 के लिए: जोश स्मिथ के एमवीएमएमउंडेशन में 'मेसेंजर' क्लास है जो वीएम में संदेशों को पास करने के लिए रजिस्टर/नोटिफिकेशन तंत्र का उपयोग करती है। वे स्मृति रिसाव से बचने के लिए कमजोर संदर्भ के रूप में संग्रहीत हैं, और वास्तव में अच्छी तरह से काम करते हैं! – kiwipom

+1

हाँ, मैं एमवीवीएम फाउंडेशन में 'मैसेंजर' कक्षा की भी सिफारिश करता हूं। उत्तम सामग्री। – Oskar

+1

हां - जब मैंने "संदेशों को पास करने के लिए संदेश" का उल्लेख किया था, तो मैं यही सोच रहा था। यह एक प्रभावी तकनीक है, यदि आप नहीं चाहते कि DI सेवाओं को इंजेक्ट करे। –

0

आप आदेश के साथ ही नियंत्रण के बीच कुछ दृश्य मॉडल वस्तुओं साझा कर सकते हैं ...

उदाहरण के लिए, यदि आप कुछ मुख्य नियंत्रण है, जो दो अन्य नियंत्रण शामिल है। और आपके पास मुख्य नियंत्रण में कुछ फ़िल्टरिंग कार्यक्षमता है, लेकिन आप उपयोगकर्ता को पहले उप-नियंत्रण (जैसे "पूर्ण फ़िल्टर") में फ़िल्टर के कुछ हिस्से को सेट करने और दूसरे में फ़िल्टर के कुछ हिस्से को सेट करने की अनुमति देना चाहते हैं (जैसे "त्वरित फ़िल्टर ")। इसके अलावा आप किसी भी उप-नियंत्रण से फ़िल्टरिंग शुरू करने में सक्षम होना चाहते हैं। तो फिर तुम इस तरह कोड इस्तेमाल कर सकते हैं:

public class MainControlViewModel : ObservableObject 
{ 
    public FirstControlViewModel firstControlViewModel; 
    public SecondControlViewModel firstControlViewModel; 

    public ICommand FilterCommand; 
    public FilterSettings FilterSettings; 

    public MainControlViewModel() 
    { 
     //... 

     this.firstControlViewModel = new FirstControlViewModel(this.FilterSettings, this.FilterCommand); 
     this.secondControlViewModel = new SecondControlViewModel(this.FilterSettings, this.FilterCommand); 
    } 
} 

public class FirstControlViewModel : ObservableObject 
{ 
    //... 
} 

public class SecondControlViewModel : ObservableObject 
{ 
    //... 
} 

मुख्य नियंत्रण XAML में आप उचित देखें मॉडल के लिए उप नियंत्रण DataContext बाध्य होगा। जब भी एक उप-नियंत्रण फ़िल्टर सेटिंग बदलता है या कमांड निष्पादित करता है तो अन्य उप-नियंत्रण अधिसूचित किया जाएगा।

3

इसके लिए कई differenct तंत्र हैं, लेकिन आपको सबसे पहले अपने आर्किटेक्चर की परत में यह पता लगाना चाहिए कि यह संचार संबंधित है।

एमवीवीएम ढांचे के उद्देश्यों में से एक यह है कि अलग-अलग विचार उसी व्यूमोडेल पर किए जा सकते हैं। क्या वे उपयोगकर्ता नियंत्रण केवल उस दृश्य में एक-दूसरे से बात करेंगे जो आप वर्तमान में कार्यान्वित कर रहे हैं, या क्या उन्हें अन्य संभावित विचारों में एक-दूसरे से बात करनी होगी? बाद के मामले में, आप व्यूमोडेल या मॉडल में दृश्य स्तर के नीचे इसे कार्यान्वित करना चाहते हैं।

पहला मामला का एक उदाहरण हो सकता है यदि आपका एप्लिकेशन बहुत छोटी डिस्प्ले सतह पर चल रहा हो। हो सकता है कि आपके उपयोगकर्ता नियंत्रण को दृश्य स्थान के लिए प्रतिस्पर्धा करनी पड़े। यदि उपयोगकर्ता अधिकतम करने के लिए एक उपयोगकर्ता नियंत्रण क्लिक करता है, तो दूसरों को कम करना चाहिए। इसका दृश्यमान के साथ कुछ लेना देना नहीं होगा, यह सिर्फ प्रौद्योगिकी के लिए अनुकूल है।

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

इस संचार की आवश्यकता मॉडल में भी हो सकती है। हो सकता है कि आपके पास डेटा को डिमॉर्मलाइज्ड किया गया हो जो अपडेट हो क्योंकि अन्य डेटा बदल गए हैं। फिर मॉडल में बदलाव के लहरों के कारण कार्रवाई में आने वाले विभिन्न व्यूमोडल्स को बदलना चाहिए।

तो, योग करने के लिए: "यह निर्भर करता है ...."

0

के रूप में अन्य लोगों ने कहा कि आप विकल्पों में से एक जोड़ी है।

अपने उपयोगकर्ता नियंत्रण पर DepedencyProperties उजागर और उन गुणों के लिए बाध्य ज्यादातर मामलों में एक शुद्ध XAML समाधान प्रदान करता है, लेकिन एक दूसरे को

अन्य विकल्प देखने के लिए बाइंडिंग के लिए क्रम में कुछ यूआई निर्भरता लागू कर सकते हैं एक decoupled मैसेजिंग पैटर्न है ViewModels के बीच संदेश भेजने के लिए। मैं आपके उपयोगकर्ता नियंत्रण को अपने स्वयं के वीएम पर गुणों से जोड़ता हूं और फिर उस वीएम के अंदर संपत्ति परिवर्तन पर यह एक संदेश "प्रकाशित" कर सकता है जो अन्य "ग्राहकों" को सूचित करता है कि कुछ हुआ है और वे उस संदेश पर प्रतिक्रिया दे सकते हैं, हालांकि वे ।

मैं अगर यह मदद करता है यह बहुत ही विषय पर एक ब्लॉग पोस्ट किया है: http://www.bradcunningham.net/2009/11/decoupled-viewmodel-messaging-part-1.html

0

आप सख्त MVVM का उपयोग कर रहे है, तो उपयोगकर्ता के नियंत्रण एक दृश्य है और केवल इसे ही "बात" हैं, या बल्कि, बाँध, इसके व्यूमोडेल में। चूंकि आपके व्यू मॉडेल सबसे पहले से ही इनोटिफाप्रोपर्टी को लागू कर चुके हैं, जब तक कि उनके पास एक-दूसरे का संदर्भ हो, वे प्रॉपर्टी चेंजेड इवेंट्स का उपयोग कर सकते हैं जब गुण बदलते हैं, या वे प्रत्येक के साथ संवाद करने के लिए विधियों (बेहतर इंटरफ़ेस के माध्यम से) कॉल कर सकते हैं अन्य।

+0

तो आपका मतलब है कि यदि दो उपयोगकर्ता नियंत्रण एक दूसरे से बात करनी है, तो उन्हें अपने संबंधित वीएम के माध्यम से करना चाहिए? और मुझे नहीं लगता कि मैं इस बिंदु से काफी सहमत हूं कि उन्हें एक-दूसरे की संपत्ति बदलने वाली घटना की सदस्यता लेनी चाहिए। – Sandbox

+0

@ सैंडबॉक्स: इस मामले में जहां आप सच्चे एमवीवीएम का उपयोग कर रहे हैं, तो व्यू इसके व्यूमोडेल के बारे में जानता है, लेकिन दृश्यों को एक दूसरे के बारे में नहीं पता होना चाहिए, इसलिए नहीं, उन्हें सीधे एक-दूसरे से बात नहीं करनी चाहिए। यदि आप इसे इस तरह से करते हैं तो इंटर-व्यू संचार की इकाई परीक्षण करने के लिए आपको कठोर दबाव डाला जाएगा।और आप किसी भी विधि के बारे में जानने या संवाद करने के लिए ViewModels के लिए जो भी तरीका चाहते हैं उसका उपयोग कर सकते हैं। .NET विकल्पों से भरा है। जो कुछ भी फिट बैठता है उसका प्रयोग करें। –

7

आपका वैचारिक समस्या यहाँ है:

प्रत्येक उपयोगकर्ता नियंत्रण एक इसी वीएम है।

प्रत्येक दृश्य के लिए एक अलग व्यूमोडेल होने से एक व्यूमोडेल की अवधारणा को काफी हद तक हराया जाता है। ViewModels विचारों के साथ एक-एक नहीं होना चाहिए, अन्यथा वे कुछ भी नहीं बल्कि गौरव कोड के पीछे हैं।

एक ViewModel की "वर्तमान यूजर इंटरफेस राज्य" की अवधारणा को दर्शाता है - जैसे क्या आप जिस पृष्ठ पर और चाहे या नहीं आप संपादन कर रहे हैं के रूप में -। के रूप में करने के लिए "वर्तमान डेटा मानों का विरोध '

वास्तव में काटते करने के लिए एमवी-वीएम के लाभ, राज्य की आवश्यकता वाले विशिष्ट वस्तुओं के आधार पर उपयोग किए गए व्यूमोडेल कक्षाओं की संख्या निर्धारित करते हैं। उदाहरण के लिए, यदि आपके पास आइटमों की एक सूची है जिसमें से प्रत्येक को 3 राज्यों में प्रदर्शित किया जा सकता है, तो आपको प्रति आइटम एक वीएम की आवश्यकता होती है। , यदि आपके पास तीन दृश्य हैं जो सभी सामान्य सेटिंग के आधार पर 3 अलग-अलग तरीकों से डेटा प्रदर्शित करते हैं, तो सामान्य सेटिंग को एक ही वीएम में पकड़ा जाना चाहिए।

एक बार जब आप अपने व्यू मॉड्यूल को प्रतिबिंबित करने के लिए हाथ में कार्य की आवश्यकताओं को आम तौर पर आप पाते हैं कि विचारों के बीच राज्य को संवाद करने की कोई ज़रूरत नहीं है और न ही इच्छा है। यदि ऐसी कोई ज़रूरत है, तो सबसे अच्छा काम यह है कि आपके व्यू मॉडेल डिज़ाइन का फिर से मूल्यांकन करना है यह देखने के लिए कि कोई साझा व्यूमोडेल अतिरिक्त राज्य जानकारी से थोड़ी सी राशि से लाभ उठा सकता है या नहीं।

ऐसे समय होंगे जब आवेदन की जटिलता एक ही मॉडल ऑब्जेक्ट के लिए कई व्यूमोडल्स के उपयोग को निर्देशित करती है। इस मामले में ViewModels एक सामान्य स्थिति वस्तु के संदर्भ रख सकते हैं।

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