2010-03-29 16 views
12

पर संदर्भ देखें मैं एक WPF ऐप में एमवीवीएम का उपयोग कर रहा हूं। मैं दोनों के लिए बहुत नया हूँ। मुझे बताएं कि मैं एमवीवीएम पैटर्न में सबसे शुद्ध नहीं हूं, मैं जितना संभव हो उतना सर्वोत्तम अभ्यास करने की कोशिश कर रहा हूं, लेकिन मुझे लगता है कि यह मेरे पर्यावरण में काम करने के लिए उचित समझौता करने का प्रयास कर रहा है। उदाहरण के लिए, मैं अपने व्यू कोडबेंड में 0% कोड प्राप्त करने की कोशिश नहीं कर रहा हूं।एमवीवीएम व्यूमोडेल

मेरे पास सर्वोत्तम प्रथाओं के बारे में कुछ प्रश्न हैं।

1) मैं समझता हूं कि मैं नहीं चाहता कि मेरा वीएम संलग्न दृश्य के बारे में जान सके, लेकिन क्या दृश्य के लिए इसके वीएम का संदर्भ होना उचित है?

2) यदि किसी दृश्य में कोई नियंत्रण किसी अन्य दृश्य को खोलता है (जैसे एक संवाद) क्या मुझे इसे दृश्य में संभालना चाहिए? वीएम में इसे संभालना गलत लगता है क्योंकि वीएम के पास एक विशिष्ट दृश्य का कुछ ज्ञान है।

+0

एक दृश्य एक वीएम संदर्भित करता है लेकिन यह अन्य तरीका नहीं होना चाहिए। http://stackoverflow.com/a/3670669/1977871 – VivekDev

उत्तर

10

1) दृश्य निश्चित रूप से DataContext के माध्यम से ViewModel का संदर्भ है। और आप अपने दृश्य में DataContext कास्ट करने के लिए अनुमति दी जाती है:

public class ShellView : Window 
{ 
    … 
    public ShellViewModel { get { return DataContext as ShellViewModel; } } 

इस मॉडल-व्यू-ViewModel पैटर्न के साथ उल्लंघन नहीं है।

2) आप सही हैं। एक ViewModel एक और दृश्य नहीं खोलना चाहिए। नियंत्रकों का उपयोग करने के लिए एक बेहतर तरीका है। वे एक आवेदन के वर्कफ़्लो के लिए ज़िम्मेदार हैं।

यदि आप अधिक विस्तृत जानकारी में रुचि रखते हैं तो आपको WPF Application Framework (WAF) पर एक नज़र डालें।

+0

+1 # 2 बिट के लिए जेबी के स्पष्टीकरण पर विस्तार करने के लिए, आप वीएम पर एक कमांड का पर्दाफाश कर सकते हैं जो नियंत्रक के कमांड हैंडलर को वायर्ड किया गया है जो दूसरे दृश्य को प्रदर्शित करने में संभाल लेगा। डब्ल्यूएएफ के अलावा, आप पी एंड पी टीम की समग्र एप्लिकेशन लाइब्रेरी (उर्फ प्रिज्म) भी देख सकते हैं: http://compositewpf.codeplex.com/Wikipage –

+0

हाँ, स्पष्ट रूप से व्यू डेटाकॉन्टेक्स्ट के माध्यम से वीएम के बारे में जानता है, मुझे लगता है कि मैं बस यह नहीं देखा था कि चूंकि मेरे xaml में बाध्यकारी सभी डेटा वीएम पर इतने निर्भर हैं कि मेरे दृश्य कोड में इसका एक मजबूत संदर्भ होने के कारण शायद ही कोई बुरी चीज की तरह दिखता है। और नियंत्रकों पर टिप के लिए धन्यवाद, मैं उस पैटर्न को देख लूंगा। – BrettRobi

+0

'सार्वजनिक शैल व्यू मॉडेल मॉडल {प्राप्त करें DataContext को ShellViewModel के रूप में प्राप्त करें; }} ' –

2

1)। दृश्य को कुछ स्तर पर दृश्य मॉडल के संदर्भ की आवश्यकता होगी, क्योंकि व्यूमोडेल दृश्य के डेटाकॉन्टेक्स्ट के रूप में कार्य करेगा।

2) एक तरीका यह संभाल करने के लिए, एक सामान्यीकृत viewmodel एक संवाद का प्रतिनिधित्व करने के लिए है कि मुख्य viewmodel के स्वामित्व में है (एक बार देखा गया DataContext रूप में इस्तेमाल किया जा रहा है।)

आप टोकरा के लिए एक आदेश का उपयोग कर सकते एक संवाद दृश्य मॉडल का एक नया उदाहरण, जिसमें आपके संसाधनों में परिभाषित एक समान डेटामैप्लेट होगा। यह टेम्पलेट संवाददृश्य मॉडल प्रकार से जुड़ने के लिए सेट किया जाएगा।

+0

+1 लेकिन मुझे लगता है कि बिंदु 1 के लिए), ओपी पूछ रहा था कि व्यू क्लास के लिए सटीक व्यूमोडेल क्लास के बारे में जानने के लिए ठीक है या नहीं, बस बस संपत्ति नामों के माध्यम से अज्ञात प्रकार का डेटाैकेंटेक्स्ट। –

+0

प्रति विम, वास्तव में मैं व्यू क्लास का जिक्र कर रहा था, जिसमें व्यूमोडेल का संदर्भ नहीं था, न केवल डाटाबेसिंग (जो सार है) के माध्यम से। – BrettRobi

+0

बिंदु # 2 पर। मैं एमवीवीएम लाइट टूलकिट का उपयोग कर रहा हूं जिसमें मैं दृश्य बनाता हूं, जो तब लोकेटर सेवा के माध्यम से व्यूमोडेल से जुड़ जाता है। इसलिए मैं वीएम नहीं बना रहा हूं, क्योंकि वे नहीं जानते कि खुद को एक दृश्य कैसे संलग्न करें। तो ऐसा लगता है कि मुझे संवाद दृश्य बनाने का एक तरीका चाहिए, और यह कहां होना चाहिए (देखें या वीएम)? – BrettRobi

3

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

public View(ViewModel vm) 
{ 
    View.DataContext = vm; 
} 

public Bootstrapper(View v, ViewModel vm) 
{ 
    v.DataContext = vm; 
    //or, if you want it to have no parameters 
    View v = new View(); 
    ViewModel vm = new ViewModel(); 
    v.DataContext = vm; 
} 

पहला विकल्प बुरा नहीं है, लेकिन वहां MVVM का स्वाद है कि किसी भी कोड पसंद नहीं करता है देखें कोड-पीछे। दूसरा विकल्प बुरा नहीं है, आपके काम के लिए काफी सरल होना चाहिए।

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

+0

धन्यवाद, फीडबैक की सराहना की जाती है – BrettRobi

1

Build Your Own MVVM Framework

मैं दृष्टिकोण रोब Eisenberg बहुत ही दिलचस्प ने सुझाव दिया पाया।

मुख्य बिंदु: विन्यास

  • ViewModel पहले
  • से अधिक

    1. कन्वेंशन कौन सा बहुत ASP.NET MVC दर्शन के समान है।

      मैं अत्यधिक वीडियो देखने की अनुशंसा करता हूं।

    2

    काफी देर हो चुकी है, लेकिन मुझे लगता है कि यह कई अलग-अलग दृष्टिकोणों के लायक होने के लिए काफी मुश्किल है।


    मैं समझता हूँ कि मैं अपने वीएम संलग्न दृश्य के बारे में पता करने के लिए नहीं करना चाहते हैं, लेकिन यह उचित देखें अपने वी एम के लिए एक संदर्भ के लिए के लिए है?

    जैसा कि पहले से ही उत्तर दिया गया है, उचित दृश्य-दृश्य मॉडल व्यवस्था में व्यूमोडेल को व्यू की डेटा कॉन्टेक्स्ट संपत्ति के रूप में असाइन किया गया है। इससे डाटाबेसिंग को घोषित एक्सएएमएल से स्थापित "स्वचालित रूप से" या कोड के पीछे ठीक-ठीक किया जा सकता है।

    var dc = DataContext as CleverViewModel; 
    CleverViewModel.CleverProperty.Add(someValue); // just a simple example 
    

    मैं चीजों DataContext कास्ट करने के लिए नहीं है इस तरह की प्राप्त करने के लिए उचित तरीके से विश्वास करते हैं, लेकिन इसके बजाय:

    कभी कभी, आप लिखने के लिए, अपने कोड में पीछे, कुछ इस तरह परीक्षा कर दिया जाएगा:

    1. दृश्य में कुछ समर्पित नियंत्रण, उदाहरण के लिए एक ItemsControl कुछ संपत्ति करने के लिए अपने ItemsSource दो तरह डेटाबाउंड साथ viewmodel में है:

      <ItemsSource x:Name="cleverControl" Visibility="Collapsed" ItemsSource="{Binding CleverProperty, Mode=TwoWay}"/>

    2. कास्ट पूरे ViewModel के बजाय बाध्य संपत्ति, कोड में पीछे:

      var collection = (ObservableCollection<double>)cleverControl.ItemsSource; collection.Add(someValue);

    नोट महत्वपूर्ण अंतर: इस उदाहरण में दूसरा दृष्टिकोण की आवश्यकता नहीं है ViewModel प्रकार को जानने के लिए देखें, इसे केवल नाम की एक संपत्ति की आवश्यकता है ObservableCollection<double>। यह मुझे पॉलिमॉर्फिक या यहां तक ​​कि बतख-टाइप किए गए व्यू मॉडल्स की अनुमति देता है।


    एक दृश्य में एक नियंत्रण (जैसे एक संवाद के रूप में) एक और देखें मैं दृश्य में इस संभाल चाहिए खोलता है? के बाद से वीएम में इसे संभालना गलत लगता है तो वीएम के पास एक विशिष्ट दृश्य का कुछ ज्ञान है।

    यह सख्त एमवीवीएम में नहीं होना चाहिए, और डेटा टेम्पलेट का उपयोग करने से बचना मुश्किल नहीं है।DataTemplates देखने का एक दिया प्रकार के DataContext की दी गई प्रकार के नक्शे, इसलिए कभी भी एक ContentControl परिवर्तन की DataContext, अपने प्रदर्शन में भी परिवर्तन होता है, बशर्ते आप उस प्रकार के लिए एक DataTemplate है:

    1. ध्यान में रखते हुए एक नियंत्रण ViewModel में कमांड भेज सकता है, जो बदले में अपनी कुछ संपत्तियों को अपडेट करेगा, जो दृश्य द्वारा प्रतिबिंबित होंगे।

    2. एक दृश्य में व्यूमोडेल के ज्ञान के बाहर एक और दृश्य हो सकता है। इस मामले में, पीछे वाला कोड निहित दृश्य के डेटाकॉन्टेक्स्ट में हेरफेर कर सकता है।

    अधिक सूक्ष्मताएं हैं, लेकिन मैं अच्छे परिणामों के साथ इस दृष्टिकोण का उपयोग कर रहा हूं। उम्मीद है कि यह किसी की मदद करता है।

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