2010-07-15 16 views
13

मेरे पास एक दृश्य है जो DataGrid प्रदर्शित करता है जो व्यूमोडेल में ObservableCollection से जुड़ा हुआ है। चर्चा के लिए, मान लीजिए कि हमारे पास Team एक टीम DataGrid है, जिसमें प्रत्येक पंक्ति Player का प्रतिनिधित्व करती है।एक दृश्य के साथ जुड़े एकाधिक दृश्य मॉडल

मेरा प्रश्न है कि मेरे Team संग्रह में खिलाड़ियों का प्रतिनिधित्व करने के लिए मुझे किस डेटा प्रकार का उपयोग करना चाहिए। क्या संग्रह में आइटमों के लिए खुद को एक अच्छा विचार है? इस मामले में, मेरे Team देखें एक Team व्यूमोडेल के साथ-साथ Player व्यू मॉडेल (टीम संग्रह में) के साथ भी जोड़ा जाएगा।

क्या एक व्यू से जुड़े एकाधिक व्यूमोडल्स एमवीवीएम के लिए किसी भी डिजाइन दिशानिर्देश का उल्लंघन करते हैं, और क्या इस परिदृश्य को लागू करने का एक पसंदीदा तरीका है?

धन्यवाद!

उत्तर

28

कोई भी ठीक नहीं है; प्रत्येक ऑब्जेक्ट को अपने स्वयं के दाएं दृश्य में होना चाहिए। यह क्लीनर कोड, नाइसर इंटरैक्शन के लिए बनाता है, और याद रखें, अगर यह अच्छी तरह से काम करता है तो यह सही है (भले ही यह दिशानिर्देशों का उल्लंघन करता हो)।

मैं इसे ठीक वैसे ही करूँगा जिस तरह से आप निर्धारित कर रहे हैं। मैं अपने ग्रिड को Team पर बांध दूंगा, जिसमें ObservableCollection<Player> होगा, जहां Player एक और व्यू मॉडेल-टाइप क्लास है। प्रत्येक पंक्ति वस्तु Player को DataContext के रूप में प्राप्त करेगी और इसलिए आप अभी भी व्यूमोडेल गुणों के लिए बाध्यकारी हैं जैसा कि आप उम्मीद करेंगे: और Player में अभी भी ICommand एस (संभवतः रिलेकॉमैंड्स) के लिए हेरफेर के लिए गुण हो सकते हैं!

आशा है कि मदद करता है!

+5

+1 "अगर यह अच्छी तरह से काम करता है तो यह सही है (भले ही यह दिशानिर्देशों का उल्लंघन करता हो)" – andyp

+0

कोई मजाक नहीं। मेरे द्वारा +1 भी। –

+1

मुझे "अगर यह सही काम करता है" से मुझे एक लॉल मिला है, लेकिन मैंने बहुत सी चीजें देखी हैं जो काम करती हैं और अब तक सही हैं, वे मुझे फेंकना चाहते हैं। :) – CindyH

9

दिशानिर्देशों का उल्लंघन करने से बहुत दूर, मुझे लगता है कि यह अनुशंसित डिज़ाइन है। कम से कम मेरी परियोजनाओं में आप बार-बार इस पैटर्न को देखेंगे।

यह पैटर्न डेटा टेम्पलेट्स के साथ विशेष रूप से उपयोगी में आता है। यदि आप तो आप बस अपने TeamViewModel.Players ObservableCollection और आप के लिए एक ListBox आदि बाँध खिलाड़ियों की एक सूची प्रदर्शित करना चाहता था

<DataTemplate DataType="viewModels:PlayerViewModel"> 
    <StackPanel Orientation="Vertical"> 
     <Image Source="/Images/Player.png"/> 
     <TextBlock Text="{Binding Name}"/> 
    </StackPanel> 
</DataTemplate> 

और फिर उदाहरण के लिए: यदि आप ऐसा तरह अपने PlayerViewModel के लिए अपने Application.Resources में एक DataTemplate निर्धारित कर सकते हैं

<ListBox ItemsSource="{Binding Players}"/> 
2

मैं अन्य उत्तर (Kieren और Groky द्वारा वाले) दोनों के साथ सहमत हैं, लेकिन वे इस फैसले में एक बहुत महत्वपूर्ण विचार उल्लेख करने में विफल महसूस: स्वचालित रूप से ऊपर DataTemplate प्रत्येक खिलाड़ी के लिए दिखाया गया है मिलता है।

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

उदाहरण के लिए, मान लीजिए:

  1. आपका प्लेयर वस्तु एक नाम संपत्ति, एक रैंक संपत्ति, एक को बढ़ावा देने के() विधि है, और एक हटाएँ() विधि है।
  2. आपका विचार एक साधारण है जो आपको किसी भी खिलाड़ी का नाम और रैंक संपादित करने की अनुमति देता है, और इसमें खिलाड़ियों को बढ़ावा देने और हटाने के लिए बटन भी हैं।

इस मामले में आपके दृश्य और आपके मॉडल के बीच एक दृश्य मॉडल जोड़ना व्यर्थ है। इस तरह के एक दृश्य के मॉडल के लिए सीधे बाध्य कर सकते हैं: रैंक संपत्ति के नाम संपत्ति

  • बाइंड Slider.Value को

    • बाइंड TextBox.Text
    • बाइंड विधि को बढ़ावा देने के() के लिए बटन को बढ़ावा देना
    • हटाएँ() विधि के लिए हटाएं बटन आबद्ध

    ध्यान दें कि बजाय हटाएँ() विधि के लिए हटाएं बटन बंधन की आप ApplicationCommands.Delete करने के लिए अपने आदेश की स्थापना की और आह्वान करने के लिए एक CommandBinding उपयोग कर सकते हैं हटाएं() विधि।

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

    मेरे अनुभव में, यदि मॉडल सही ढंग से डिजाइन किया गया है तो केवल 50% या सभी विचारों के लिए वास्तव में एक दृश्य मॉडल की आवश्यकता है, और सूची में वस्तुओं के मामले में यह 20% की तरह है।

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

  • +0

    उद्धरण: "इस तरह का एक दृश्य सीधे मॉडल पर बाध्य हो सकता है: बाइंड टेक्स्टबॉक्स। नाम संपत्ति के आगे बाइंड स्लाइडर। रैंक संपत्ति के लिए मूल्य प्रचार() विधि में प्रचार बटन को बाध्य करें" जब से कोई मॉडल में एक विधि है? हटाएं() विधि – Elisabeth

    +0

    पर हटाएं बटन को बाध्य करें लगभग सभी मॉडलों में विधियां हैं। विधियों के बिना एक मॉडल मांसपेशियों के बिना एक व्यक्ति की तरह होगा। विधियों के बिना, आप मॉडल को कुछ भी करने के लिए कैसे कहेंगे? क्या आप 'person.Clap() '' person.Clap = true' या' PersonOperations.Clap (person) 'के साथ 'person.Clap()' को प्रतिस्थापित करेंगे? इनमें से कोई भी सबसे अच्छा अजीब लग रहा है। ऑब्जेक्ट उन्मुख प्रोग्रामिंग से पहले संरचित प्रोग्रामिंग किया गया था, जिसमें आप 'पर्सनलक्लप (व्यक्ति * व्यक्ति)' फ़ंक्शन बना सकते हैं, लेकिन आईएमएचओ चीजों को व्यक्त करने का ऑब्जेक्ट उन्मुख तरीका बहुत साफ है। –

    +0

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

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