2009-03-17 11 views
9

मेरे पास एक एमवीवीएम एप्लीकेशन है। व्यूमोडल्स में से एक में 'FindFilesCommand' है जो एक ऑब्जर्जेबल कोलेक्शन को पॉप्युलेट करता है। मैं फिर एक ही ViewModel में 'RemoveFilesCommand' लागू करता हूं। यह आदेश तब कुछ और उपयोगकर्ता इनपुट प्राप्त करने के लिए एक विंडो लाता है।मॉडल दृश्य में नई विंडो लाने के लिए सबसे अच्छी जगह ViewModel

एमवीवीएम प्रतिमान को ध्यान में रखते हुए ऐसा करने का सबसे अच्छा तरीका कहां है/कहां है? किसी तरह कर:

new WhateverWindow().Show()

ViewModel में गलत लगता है।

चीयर्स,

स्टीव

+0

मैंने [इस पोस्ट] में एक बहुत ही समान प्रश्न का उत्तर दिया है (http://stackoverflow.com/a/15512972/385995)। –

उत्तर

2

मैं व्यक्तिगत रूप से इस परिदृश्य को एक ऐसे रूप में देखता हूं जहां मुख्य विंडो दृश्य मॉडल अंतिम उपयोगकर्ता को पूरा करने के लिए एक कार्य को सतह बनाना चाहता है।

यह कार्य बनाने और इसे आरंभ करने के लिए ज़िम्मेदार होना चाहिए। दृश्य को बच्चे की खिड़की बनाने और दिखाने के लिए जिम्मेदार होना चाहिए, और कार्य को नए तत्काल विंडो के दृश्य मॉडल के रूप में उपयोग करना चाहिए।

कार्य रद्द या प्रतिबद्ध किया जा सकता है। यह पूरा होने पर अधिसूचना उठाता है।

खिड़की स्वयं को बंद करने के लिए अधिसूचना का उपयोग करती है। फॉलोअप कार्य होने पर कार्य करने के बाद पैरेंट व्यू मॉडल अतिरिक्त कार्य करने के लिए अधिसूचना का उपयोग करता है।

मेरा मानना ​​है कि यह प्राकृतिक/अंतर्ज्ञानी चीज़ के करीब है जो लोग अपने कोड-पीछे दृष्टिकोण के साथ करते हैं, लेकिन यूआई-स्वतंत्र चिंताओं को एक दृश्य मॉडल में विभाजित करने के लिए दोबारा प्रतिक्रिया दी जाती है, बिना अतिरिक्त वैचारिक ओवरहेड जैसे सेवाएं आदि।

मेरे पास सिल्वरलाइट के लिए इसका कार्यान्वयन है। अधिक जानकारी के लिए http://www.nikhilk.net/ViewModel-Dialogs-Task-Pattern.aspx देखें ... मुझे इस पर टिप्पणियां/और सुझाव सुनना अच्छा लगेगा।

-1

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

कमांड ऑब्जेक्ट्स यह दिखाने के लिए पर्याप्त हैं कि संवाद बाकी सॉफ़्टवेयर के साथ कैसे बातचीत कर रहा है। अपने स्वयं के सॉफ़्टवेयर में कमांड ऑब्जेक्ट्स अपने पुस्तकालयों में रहते हैं ताकि संवाद शेष सिस्टम से छिपा हुआ हो।

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

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

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

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

+0

हाय। मुझे लगता है कि व्यूमोडेल में ठोस संवाद होने से टेस्टेबिलिटी टूट जाएगी। –

0

मैंने इस समस्या को एमवीवीएम के साथ भी चलाया है। मेरा पहला विचार संवाद का उपयोग न करने का तरीका खोजने का प्रयास करना है। डब्ल्यूपीएफ का उपयोग करना एक संवाद के मुकाबले चीजों को करने के लिए एक चंचल तरीके से आना बहुत आसान है।

जब यह संभव नहीं है, तो सबसे अच्छा विकल्प उपयोगकर्ता से जानकारी प्राप्त करने के लिए ViewModel को साझा कक्षा को कॉल करना प्रतीत होता है। ViewModel पूरी तरह से अनजान होना चाहिए कि एक संवाद दिखाया जा रहा है।

तो, एक साधारण उदाहरण के रूप में, यदि आपको उपयोगकर्ता को हटाने की पुष्टि करने के लिए उपयोगकर्ता की आवश्यकता होती है, तो ViewModel DialogHelper.ConfirmDeletion() को कॉल कर सकता है, जो कि उपयोगकर्ता ने हाँ या नहीं कहा है, तो एक बुलियन लौटाएगा। संवाद का वास्तविक प्रदर्शन हेल्पर वर्ग में किया जाएगा।

अधिक उन्नत संवाद के लिए, बहुत सारे डेटा लौटाने के लिए, सहायक विधि को उस वस्तु से सभी जानकारी के साथ एक वस्तु वापस करनी चाहिए।

मुझे लगता है कि यह बाकी एमवीवीएम के साथ सबसे आसान फिट नहीं है, लेकिन मुझे अभी तक कोई बेहतर उदाहरण नहीं मिला है।

+0

कॉलिंग वास्तव में संवाद को कॉल करने के "DialogHelper.ConfirmDeletion()" को कोई भी डिफेंस इम्हो नहीं बनाता है। आप अभी भी कोड में शुद्ध यूआई मिश्रण कर रहे हैं। (आखिरकार, डायलॉग हेल्पर पहले ही सुझाव देता है कि यह एक खिड़की वाला सहायक है ...) –

+0

मैं सहमत हूं, लेकिन मुझे ऐसा करने के लिए कोई बेहतर तरीका नहीं दिख रहा है। संवाद को ViewModel से काम करने के लिए प्रदर्शित किया जाना है। मुझे लगता है कि व्यूमोडेल कम से कम स्पष्ट रूप से संवाद प्रदर्शित नहीं कर रहा है, हालांकि यह एक अच्छा कदम है। इस तरह संवाद को पुन: उपयोग किया जा सकता है और कम से कम प्रयास के साथ मजबूती से बदला जा सकता है। – timothymcgrath

+0

मुझे लगता है कि शायद घटनाएं जाने का रास्ता हो सकता है? अभी तक विवरणों के बारे में निश्चित नहीं है और यह शुद्ध एमवीवीएम के साथ कैसे फिट होगा। –

0

मुझे कहना होगा, सेवाएं यहां जाने का तरीका हैं।

सेवा इंटरफ़ेस डेटा लौटने का एक तरीका प्रदान करता है। फिर उस सेवा का वास्तविक कार्यान्वयन इंटरफ़ेस में आवश्यक जानकारी प्राप्त करने के लिए एक संवाद या जो कुछ भी दिखा सकता है।

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

+0

हाय। हालांकि सेवा के मालिक कौन होगा? दृश्य या मॉडल? उन स्थानों में से किसी एक में बिल्कुल सही नहीं लगता है। –

+0

आपका क्या मतलब है कि सेवा का मालिक कौन है? यह एक सिंगलटन है। इसके अलावा यदि आप सोचते हैं कि सेवा क्या प्रदान कर रही है तो यह वीएम है जो इसे कॉल करता है क्योंकि इसे हटाने की पुष्टि करने की आवश्यकता है, आदि –

+0

क्षमा करें, मेरा मतलब है 'सेवा इंटरफ़ेस किस नामस्थान में रहता है'। –

1

जैमे रोड्रिगेज और कार्ल Shifflet की Southridge अचल संपत्ति के उदाहरण में, वे viewmodel में खिड़की बना रहे हैं, और विशेष रूप से एक बाध्य आदेश के अमल भाग में:

protected void OnShowDetails (object param) 
    { 
     // DetailsWindow window = new DetailsWindow(); 
     ListingDetailsWindow window = new ListingDetailsWindow(); 
     window.DataContext = new ListingDetailsViewModel (param as Listing, this.CurrentProfile) ; 
     ViewManager.Current.ShowWindow(window, true); 
    } 

यहाँ लिंक है: http://blogs.msdn.com/jaimer/archive/2009/02/10/m-v-vm-training-day-sample-application-and-decks.aspx

मुझे लगता है कि यह एक बड़ी समस्या का नहीं है। आखिरकार, व्यूमोडेल व्यू और बिजनेस लेयर/डेटा लेयर के बीच 'गोंद' के रूप में कार्य करता है, इसलिए आईएमओ को व्यू (यूआई) के साथ जोड़ा जाना सामान्य है ...

+0

प्रतिक्रिया के लिए धन्यवाद। क्या इसका मतलब यह नहीं होगा कि व्यूमोडेल के पास लिस्टिंग डिस्प्लेविंडो (और व्यूमेनगर?) के दृश्य के लिए संदर्भ है। –

+1

नहीं, एक व्यूमोडेल आदर्श रूप से यूआई तकनीक से स्वतंत्र होना चाहिए। निश्चित रूप से यह गोंद है, लेकिन इसे किसी ठोस दृश्य पर किसी भी निर्भरता से बचने चाहिए, और यदि संभव हो तो ठोस यूआई सामान/मैकेनिक्स पर निर्भरता। – Falcon

1

गोमेद (http://www.codeplex.com/wpfonyx) काफी हद तक प्रदान करेगा इसके लिए अच्छा समाधान। उदाहरण के लिए, ICommonDialogProvider सेवा है, जो इस तरह एक ViewModel से इस्तेमाल किया जा सकता को देखो:

ICommonFileDialogProvider provider = this.View.GetService<ICommonDialogProvider>(); 
IOpenFileDialog openDialog = provider.CreateOpenFileDialog(); 
// configure the IOpenFileDialog here... removed for brevity 
openDialog.ShowDialog(); 

यह बहुत ठोस OpenFileDialog का उपयोग करने के समान है, लेकिन पूरी तरह से परीक्षण योग्य है। आपको वास्तव में आवश्यक डिकूप्लिंग की मात्रा आपके लिए एक कार्यान्वयन विवरण होगी। उदाहरण के लिए, आपके मामले में आप ऐसी सेवा चाहते हैं जो पूरी तरह से इस तथ्य को छुपाए कि आप एक संवाद का उपयोग कर रहे हैं। की तर्ज पर कुछ:

public interface IRemoveFiles 
{ 
    string[] GetFilesToRemove(); 
} 

IRemoveFiles removeFiles = this.View.GetService<IRemoveFiles>(); 
string[] files = removeFiles.GetFilesToRemove(); 

फिर आप देखें IRemoveFiles सेवा, जिसके लिए वहाँ कई आप के लिए उपलब्ध विकल्पों है के लिए एक कार्यान्वयन है सुनिश्चित करने के लिए है।

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

+0

हाय। 'This.View.GetService()': यह क्या करता है। वापसी देखें और क्या मुझे अपने 'व्यू' नामस्थान में किसी भी प्रकार के विशिष्ट संदर्भ की आवश्यकता होगी? मेरे लिए, यह अनिवार्य रूप से एमवीवीएम तोड़ने लगेगा - आपको याद है, मैं गलत हो सकता हूं - मैं इसके लिए बहुत नया हूं –

+0

यह ओनिक्स फ्रेमवर्क का एक दृश्य उदाहरण देता है। देखें एक IServiceProvider है और एक निर्भरता ऑब्जेक्ट के रूप में ViewElement (जिस तत्व में दृश्य संबद्ध है) तक पहुंच प्रदान करता है। यदि आप कभी भी ViewElement का उपयोग नहीं करते हैं तो आप एमवीवीएम सिद्धांतों का उल्लंघन नहीं कर रहे हैं। सरल नमूना देखें। – wekempf

0

हम क्या कर रहे हैं इस तरह somethng है, यहाँ क्या वर्णित है: http://www.codeproject.com/KB/WPF/DialogBehavior.aspx?msg=3439968#xx3439968xx

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

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