MVVM टेम्पलेट के अच्छे उदाहरण


141

मैं वर्तमान में Microsoft MVVM टेम्प्लेट के साथ काम कर रहा हूं और निराशा में विस्तृत उदाहरणों की कमी का पता लगाता हूं। कॉन्टेक्टबुक उदाहरण में बहुत कम कमांड हैंडलिंग दिखाया गया है और केवल एक और उदाहरण जो मैंने पाया है वह एक MSDN मैगज़ीन लेख से है जहां अवधारणाएं समान हैं लेकिन थोड़ा अलग दृष्टिकोण का उपयोग करता है और अभी भी किसी भी जटिलता में कमी है। क्या कोई सभ्य MVVM उदाहरण हैं जो कम से कम बुनियादी CRUD संचालन और संवाद / सामग्री स्विचिंग दिखाते हैं?


सभी के सुझाव वास्तव में उपयोगी थे और मैं अच्छे संसाधनों की सूची तैयार करना शुरू करूंगा

फ़्रेमवर्क / खाके

उपयोगी लेख

स्क्रीनकास्ट

अतिरिक्त पुस्तकालय


मुझे खुशी है कि इन संसाधनों ने मदद की है। मैं इस समय अपने दूसरे प्रोडक्शन एमवीवीएम एप्लीकेशन पर हूं और इसमें वह कंटेंट जोड़ना जारी रखूंगा, जो मेरे शुरू होते ही शुरू करने वालों के लिए मददगार होगा।
ज्वार

जवाबों:


59

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

प्रिज्म रिलीज़:
http://www.codeplex.com/CompositeWPF

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

प्रिज्म हर प्रोजेक्ट के लिए जरूरी नहीं है, लेकिन इससे परिचित होना अच्छी बात है।

CRUD: यह हिस्सा बहुत आसान है, WPF दो तरह से बाँधने से अधिकांश डेटा को संपादित करना वास्तव में आसान हो जाता है। असली चाल एक मॉडल प्रदान करना है जो यूआई स्थापित करना आसान बनाता है। बहुत कम से कम आप यह सुनिश्चित करना चाहते हैं कि आपका ViewModel (या व्यावसायिक ऑब्जेक्ट) INotifyPropertyChangedबाइंडिंग का समर्थन करने के लिए लागू होता है और आप संपत्तियों को सीधे UI नियंत्रणों से बाँध सकते हैं, लेकिन आप IDataErrorInfoसत्यापन के लिए भी लागू करना चाह सकते हैं । आमतौर पर, यदि आप किसी प्रकार के ORM समाधान का उपयोग करते हैं तो CRUD एक सेटिंग है।

यह आलेख सरल क्रूड संचालन प्रदर्शित करता है: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx

यह LinqToSql पर बनाया गया है, लेकिन यह उदाहरण के लिए अप्रासंगिक है - यह सब महत्वपूर्ण है कि आपकी व्यावसायिक वस्तुएं लागू होती हैं INotifyPropertyChanged(जो कि LinqToSql द्वारा उत्पन्न कक्षाएं होती हैं)। MVVM उस उदाहरण का बिंदु नहीं है, लेकिन मुझे नहीं लगता कि इस मामले में यह मायने रखता है।

यह आलेख डेटा सत्यापन http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx प्रदर्शित करता है

फिर से, अधिकांश ORM समाधान उन कक्षाओं को उत्पन्न करते हैं जो पहले से ही लागू होते हैं IDataErrorInfoऔर आमतौर पर कस्टम सत्यापन नियमों को जोड़ना आसान बनाने के लिए एक तंत्र प्रदान करते हैं।

अधिकांश समय आप किसी ORM द्वारा बनाई गई कोई वस्तु (मॉडल) ले सकते हैं और इसे ViewModel में लपेट सकते हैं जो इसे सहेजता / हटाता है - और आप UI को मॉडल के गुणों से सीधे बाँधने के लिए तैयार हैं।

दृश्य कुछ इस तरह दिखाई देगा (ViewModel के पास Itemमॉडल रखने वाली एक संपत्ति है, जैसे ORM में बनाया गया वर्ग):

<StackPanel>
   <StackPanel DataContext=Item>
      <TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
      <TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
   </StackPanel>
   <Button Command="{Binding SaveCommand}" />
   <Button Command="{Binding CancelCommand}" />
</StackPanel>

संवाद: संवाद और MVVM थोड़ा मुश्किल हैं। मैं संवादों के साथ मध्यस्थ दृष्टिकोण का एक स्वाद का उपयोग करना पसंद करता हूं, आप इस StackOverflow प्रश्न में इसके बारे में थोड़ा और पढ़ सकते हैं:
WPF MVVM संवाद उदाहरण

मेरा सामान्य दृष्टिकोण, जो काफी क्लासिक MVVM नहीं है, को निम्नानुसार संक्षेपित किया जा सकता है:

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

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

कहीं न कहीं आपको अपने ViewModels के लिए डेटा टेम्प्लेट प्रदान करने की आवश्यकता होती है, वे विशेष रूप से बहुत सरल हो सकते हैं क्योंकि आपके पास संभवतः एक अलग नियंत्रण में संलग्न प्रत्येक संवाद के लिए एक दृश्य है। एक ViewModel के लिए डिफ़ॉल्ट डेटा टेम्प्लेट तब कुछ इस तरह दिखाई देगा:

<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}">
   <views:AddressEditView DataContext="{Binding}" />
</DataTemplate>

संवाद दृश्य को इन तक पहुंच की आवश्यकता होती है, क्योंकि अन्यथा यह पता नहीं चलेगा कि ViewModel को कैसे दिखाया जाए, साझा किए गए संवाद UI से अलग इसकी सामग्री मूल रूप से यह है:

<ContentControl Content="{Binding}" />

अंतर्निहित डेटा टेम्पलेट दृश्य को मॉडल में मैप करेगा, लेकिन इसे कौन लॉन्च करता है?

यह नहीं तो mvvm हिस्सा है। इसका एक तरीका वैश्विक घटना का उपयोग करना है। मुझे लगता है कि एक बेहतर बात यह है कि एक घटना एग्रीगेटर टाइप सेटअप का उपयोग करना है, जो निर्भरता इंजेक्शन के माध्यम से प्रदान किया जाता है - इस तरह यह घटना एक कंटेनर के लिए वैश्विक है, न कि पूरे ऐप। प्रिज्म कंटेनर शब्दार्थ और निर्भरता इंजेक्शन के लिए एकता ढांचे का उपयोग करता है, और कुल मिलाकर मुझे एकता बहुत पसंद है।

आमतौर पर, यह इस घटना की सदस्यता के लिए रूट विंडो के लिए समझ में आता है - यह डायलॉग खोल सकता है और अपने डेटा संदर्भ को ViewModel पर सेट कर सकता है जो एक उठाए गए इवेंट के साथ पास हो जाता है।

इसे इस तरह सेट करने से ViewModels एप्लिकेशन को डायलॉग खोलने के लिए कह सकता है और यूआई के बारे में कुछ भी जाने बिना उपयोगकर्ता क्रियाओं का जवाब देता है ताकि अधिकांश भाग के लिए MVVM-ness पूरा बना रहे।

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

एक बटन हैंडलर का छद्म कोड जो एक संवाद बढ़ाता है जिसे तत्व स्थिति डेटा की आवश्यकता होती है:

ButtonClickHandler(sender, args){
    var vm = DataContext as ISomeDialogProvider; // check for null
    var ui_vm = new ViewModelContainer();
    // assign margin, width, or anything else that your custom dialog might require
    ...
    ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
    // raise the dialog show event
}

संवाद दृश्य डेटा को स्थिति में बाँध देगा, और निहित ViewModel को आंतरिक में पास करेगा ContentControl। ViewModel अभी भी UI के बारे में कुछ नहीं जानता है।

सामान्य तौर पर मैं विधि के DialogResultरिटर्न प्रॉपर्टी का उपयोग नहीं करता ShowDialog()या डायलॉग बंद होने तक थ्रेड को ब्लॉक करने की अपेक्षा करता हूं । एक गैर-मानक मोडल संवाद हमेशा उस तरह काम नहीं करता है, और एक समग्र वातावरण में आप अक्सर एक इवेंट हैंडलर को किसी भी तरह से ब्लॉक नहीं करना चाहते हैं। मैं ViewModels को इससे निपटने देना पसंद करता हूं - एक ViewModel का निर्माता इसके प्रासंगिक घटनाओं, सेट कमिट / रद्द करने के तरीकों आदि की सदस्यता ले सकता है, इसलिए इस UI तंत्र पर भरोसा करने की कोई आवश्यकता नहीं है।

इसलिए इस प्रवाह के बजाय:

// in code behind
var result = somedialog.ShowDialog();
if (result == ...

मैं उपयोग करता हूं:

// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit 
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container

मैं इसे इस तरह से पसंद करता हूं क्योंकि मेरे अधिकांश संवाद गैर-अवरुद्ध छद्म-मोडल नियंत्रण हैं और इसे इस तरह से करना इसके चारों ओर काम करने की तुलना में अधिक सीधा लगता है। यूनिट टेस्ट के लिए भी आसान।


विस्तृत उत्तर के लिए धन्यवाद! मैंने हाल ही में पाया कि मेरा सबसे बड़ा मुद्दा यह है कि जब मुझे एप्लिकेशन के प्रवाह को संभालने के लिए अन्य दृश्य मॉडल के साथ MainViewModel संवाद करने की आवश्यकता होती है। हालाँकि ऐसा प्रतीत होता है कि MVVM + मध्यस्थ लोकप्रिय दृष्टिकोण है।
बजे

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

1
संवाद और खिड़कियों के साथ काम करने के लिए दिशा-निर्देश वास्तव में मददगार रहे हैं। हालाँकि, मैं कुछ मुद्दों के साथ फंस गया हूँ: 1. आप दृश्य से खिड़की का शीर्षक कैसे निर्धारित करते हैं? 2. आप मालिक खिड़की की स्थापना के साथ कैसे व्यवहार करते हैं?
djskinner

@ डैनियल स्किनर: मैं मान रहा हूं कि आप यहां संवादों के बारे में बात कर रहे हैं, अगर मैं गलत हूं तो मुझे सुधारें। संवाद शीर्षक सिर्फ एक और संपत्ति है और आप इसे अपनी पसंद के अनुसार बाँध सकते हैं। यदि आपने बेस डायलॉग व्यूमाडेल क्लास के साथ मेरे दृष्टिकोण का अनुसरण किया है (चलो इसका शीर्षक गुण है), तो अपने सभी जेनेरिक डायलॉग विंडो में आप यूआई बाइंडिंग को यूआई बाइंडिंग का उपयोग करके टाइटल को {बाइंडिंग पाथ = DataContext.Tole, ElementName = कर सकते हैं। NameOfContentPresenter}। मालिक खिड़की एक छोटी सी चाल है - इसका मतलब है कि मध्यस्थ जो वास्तव में संवाद को पॉप अप करता है उसे रूट ऐप दृश्य के बारे में जानने की आवश्यकता होती है।
ईगोर

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

6

जेसन Dolinger एक अच्छा बनाया स्क्रीनकास्ट MVVM की। Egor की तरह वहाँ कोई एक अच्छा उदाहरण है। वे सब खत्म हो गए हैं। अधिकांश अच्छे एमवीवीएम उदाहरण हैं, लेकिन जब आप जटिल मुद्दों पर नहीं आते हैं। प्रत्येक का अपना रास्ता है। लॉरेंट बुग्नेयन के पास दृश्यमॉडल के बीच भी संवाद करने का एक अच्छा तरीका है। http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch भी एक अच्छा उदाहरण है। पॉल स्टोव की एक अच्छी पोस्ट है जो अपने मैगलन ढांचे के साथ बहुत कुछ समझाती है।


3

क्या आपने कैलिबर्न को देखा है ? कॉन्टेक्टमैनगर सैंपल में बहुत सारी अच्छी चीजें हैं। सामान्य WPF नमूने भी आदेशों का एक अच्छा अवलोकन प्रदान करते हैं। प्रलेखन काफी अच्छा है और फोरम सक्रिय हैं। सिफारिश की!



3

यहां मैं एक WPF (इन्वेंटरी मैनेजमेंट ऐप) एप्लिकेशन का लिंक जोड़ रहा हूं जो मेरे द्वारा डिजाइन किए गए MVVM आर्किटेक्चर का उपयोग कर रहा है।

इसका यूआई कमाल का है। https://github.com/shivam01990/InventoryManagement


2

सेंचुरी ढांचे में नमूना परियोजना बुनियादी सीआरयूडी और नेविगेशन उपकरण दिखाती है। यह MVVM का उपयोग करने का एक बहुत अच्छा उदाहरण है, और इसमें इसके उपयोग और प्रेरणाओं को समझाने वाला एक बहु-भाग लेख शामिल है ।


2

मैंने आपकी हताशा में भी साझा किया। मैं एक आवेदन लिख रहा हूं और मेरी ये 3 आवश्यकताएं हैं:

  • एक्सटेंसिबल
  • MVVM के साथ WPF
  • GPL संगत उदाहरण हैं

मुझे जो कुछ मिला वह बिट्स और टुकड़े थे, इसलिए मैंने इसे सबसे अच्छा लिखना शुरू कर दिया। जब मैं इसमें थोड़ा सा घुस गया, तो मुझे एहसास हुआ कि अन्य लोग (अपने आप की तरह) भी हो सकते हैं जो एक संदर्भ एप्लिकेशन का उपयोग कर सकते हैं, इसलिए मैंने एक WPF / MVVM एप्लिकेशन फ्रेमवर्क में जेनेरिक सामान को बाहर निकाल दिया और इसे LGPL के तहत जारी किया। मैंने इसका नाम SoapBox Core रखा । यदि आप डाउनलोड पृष्ठ पर जाते हैं, तो आप देखेंगे कि यह एक छोटे डेमो एप्लिकेशन के साथ आता है, और उस डेमो एप्लिकेशन का स्रोत कोड भी डाउनलोड के लिए उपलब्ध है। आशा है कि आप मददगार मिलेंगे। इसके अलावा, अगर आप अधिक जानकारी चाहते हैं, तो मुझे scott {at} सोपबॉक्सबॉक्सोमेशन.कॉम पर ईमेल करें।

संपादित करें : यह भी बताता है कि यह कैसे काम करता है एक CodeProject लेख पोस्ट किया है ।


2

मैंने कोड प्रोजेक्ट पर खरोंच से एक साधारण MVVM उदाहरण लिखा है यहाँ लिंक MVVM WPF कदम है । यह एक साधारण 3 लेयर आर्किटेक्चर से शुरू होता है और आपको PRISM जैसे कुछ ढांचे का उपयोग करने के लिए स्नातक करता है।

यहां छवि विवरण दर्ज करें


1

यहां तक ​​कि मैंने हताशा को तब तक साझा किया जब तक मैंने मामले को अपने हाथों में नहीं लिया। मैंने इनकाउंटर शुरू किया।

IncEditor ( http://inceditor.codeplex.com ) एक संपादक है जो डेवलपर्स को WPF, MVVM और MEF से परिचित कराने का प्रयास करता है। मैंने इसे शुरू किया और 'थीम' समर्थन जैसी कुछ कार्यक्षमता प्राप्त करने में कामयाब रहा। मैं WPF या MVVM या MEF का कोई विशेषज्ञ नहीं हूं इसलिए मैं इसमें बहुत अधिक कार्यक्षमता नहीं डाल सकता। मैं आप लोगों से निवेदन करता हूं कि आप इसे बेहतर बनाएं ताकि मेरे जैसे पोषक तत्व इसे बेहतर समझ सकें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.