2009-07-08 6 views
38

मैं एक WPF आवेदन जो MessageBox.Show (कॉल) जिस तरह से ViewModel में वापस मिल गया है। यह वास्तव में काम करता है, लेकिन ViewModel के बाद से MVVM के अनाज के खिलाफ जाता है स्पष्ट रूप से निर्धारित नहीं करना चाहिए देखें पर क्या होता है।आपने एमवीवीएम में MessageBox.Show() कार्यक्षमता को सफलतापूर्वक कार्यान्वित कैसे किया है? (यदि उपयोगकर्ता वास्तव में हटाना चाहता है की जाँच करने के लिए)

तो अब मैं सोच रहा हूँ कैसे मैं सबसे अच्छा मेरी MVVM आवेदन में MessageBox.Show() कार्यक्षमता लागू कर सकते हैं, विकल्प:

  1. मैं पाठ के साथ एक संदेश हो सकता है "क्या आपको यकीन है। ..? " मेरे एक्सएएमएल में दो बटनों के साथ हां और नहीं, और टेम्पलेट पर एक ट्रिगर बनाएं ताकि इसे नामक व्यूमोडेलप्रॉपर्टी के आधार पर ध्वस्त/दृश्यमान किया जा सके। AreYourSureDialogueBoxIsVisible, और फिर जब मुझे इस संवाद बॉक्स की आवश्यकता होती है, तो AreYourSureDialogueBoxIs को असाइन करें "सत्य", और मेरे ViewModel में DelegateCommand के माध्यम से दो बटन को भी संभाल लें।

  2. मैं किसी भी तरह से एक्सएएमएल में ट्रिगर्स के साथ इसे संभालने का प्रयास कर सकता हूं ताकि हटाएं बटन वास्तव में संदेश और बटन के साथ कुछ सीमा तत्व दिखाई दे, और हां बटन वास्तव में हटा रहा था।

दोनों समाधान बहुत जटिल क्या MessageBox.Show साथ कोड की एक जोड़ी लाइनों हुआ करता था के लिए होने लगते हैं()।

किस तरह से आप सफलतापूर्वक वार्ता बक्से अपने MVVM अनुप्रयोगों में लागू कर दिया है?

+0

इसी प्रकार के प्रश्न: http://stackoverflow.com/questions/315180/model-view-presenter-and-modal-dialog-boxes-how-to –

उत्तर

5

आपके द्वारा उल्लेख किए गए दो में से, मैं विकल्प # 2 पसंद करता हूं। पृष्ठ पर हटाएं बटन बस "हटाएं संवाद की पुष्टि करें" दिखाई देता है। "हटाएं संवाद की पुष्टि करें" वास्तव में हटाएं बंद कर देता है।

आप कार्ल Shifflett के WPF Line Of Business Slides and Demos की जांच की है? मुझे पता है कि वह ऐसा कुछ करता है। मैं कहां याद रखने की कोशिश करूंगा।

संपादित करें: डेमो # 11 "एमवीवीएम में डेटा प्रमाणीकरण" देखें (संपादित करें CONTactItemsControlSelectionViewModel.DeleteCommand)। कार्ल व्यूमोडाल से एक पॉपअप कहता है (क्या !? :-)। मैं वास्तव में आपके विचार को बेहतर पसंद करता हूं। यूनिट टेस्ट के लिए आसान लगता है।

+0

मैं अंत में # 1 समाधान के साथ इस हल किया। यह खिड़की नहीं खुलता है, स्क्रीन के शीर्ष पर एक सीमा तत्व "केवल" दृश्यता = दृश्यता = दृश्यमान से ध्वस्त करके इसे "सम्मिलित करता है"। मैंने DelegateCommands बनाया: TurnOnDialogueBoxDelete, DeleteItem और CancelDialogueBoxDelete। मैंने ViewModelProperties बनाई: DialogueBoxDeleteStatus, ItemIdMarkedForDeletion, और DialogueBoxDeleteText। तो यह एक साधारण संदेशबॉक्स के रूप में आसान नहीं है। दिखाएं() लेकिन यह अच्छी तरह से काम करता है। मुझे यकीन है कि आखिरकार इनमें से कुछ को दूर किया जा सकता है जब अन्य संवाद बॉक्स की आवश्यकता होती है। –

+0

और यह इकाई परीक्षण किया जा सकता है। :-) –

11

बचाव के लिए सेवाएं। Onyx का उपयोग करना (त्याग, मैं लेखक हूँ) इस रूप में आसान है:

public void Foo() 
{ 
    IDisplayMessage dm = this.View.GetService<IDisplayMessage>(); 
    dm.Show("Hello, world!"); 
} 

चल रहे एक आवेदन में, यह परोक्ष रूप से MessageBox.Show फोन करेगा ("हैलो दुनिया!")। परीक्षण करते समय, IDISplayMessage सेवा को मॉक किया जा सकता है और व्यूमोडेल को प्रदान किया जा सकता है ताकि आप परीक्षण के दौरान जो भी हासिल करना चाहते हैं।

+0

मुझे आश्चर्य है कि अगर अप्रत्यक्ष रूप से दृश्य को एक्सेस करना अभी भी एमवीवीएम अभ्यास के बाद माना जाता है। – VCD

+0

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

0

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

+6

हाँ, लेकिन यदि आप यूनिट टेस्ट में अपने व्यू मॉडल का परीक्षण कर रहे हैं, तो क्या होने जा रहा है? क्या आपका परीक्षण उपयोगकर्ता को 'हां' या 'नहीं' पर क्लिक करने के लिए इंतजार कर देगा? – esylvestre

1

मैंने शुद्ध एमवीवीएम समाधान में उपयोग करने के लिए एक सरल संदेशबॉक्स रैपर नियंत्रण बनाया है और अभी भी इकाई परीक्षण क्षमता की अनुमति देता है।विवरण मेरे ब्लॉग http://geekswithblogs.net/mukapu/archive/2010/03/12/user-prompts-messagebox-with-mvvm.aspx

mukapu

+0

लिंक में समाधान टूटा हुआ है आप इसे ठीक कर सकते हैं। –

1

मैं सिर्फ एक इंटरफेस (IMessageDisplay या समान) बनाने के जो वीएम में इंजेक्ट किया जाता है में हैं, और यह एक संदेशबॉक्स (ShowMessage() आदि) की तरह के तरीकों है। आप इसे मानक संदेशबॉक्स का उपयोग करके लागू कर सकते हैं, या कुछ और WPF विशिष्ट (मैं this one on CodePlex प्रेजेश नामक कुछ व्यक्ति का उपयोग कर सकता हूं)।

इस तरह सब कुछ अलग और परीक्षण योग्य है।

1

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

Check it out here

3

क्या ("MessageBoxRequested" देखें की codebehind में संभाला तरह की एक घटना बढ़ाने के बारे में वैसे भी यह दृश्य केवल कोड है तो मैं कोडबेहिंड पर इस कोड को रखने में कोई समस्या नहीं है)।

+0

सच है, एमवीवीएम मेरे लिए मॉडल और दृश्य को जोड़ने के लिए है। लेकिन विचार खुद पर भी व्यवहार करना चाहिए। – jeuxjeux20

1

शायद ज़रुरत पड़े किसी और को अभी भी पढ़ रही है और असंतुष्ट:

मैं सिर्फ 'सूचना' प्रकार MessageBoxes (यानी मैं DialogResult के बारे में परवाह नहीं है) को संभालने के लिए चाहता था, लेकिन समस्या मैं के साथ है मेरे द्वारा पढ़े जाने वाले अधिकांश समाधान यह है कि वे अप्रत्यक्ष रूप से आपको अपने व्यू कार्यान्वयन को चुनने के लिए मजबूर करते हैं (यानी, वर्तमान में मेरे पास MessageBox.Show है, लेकिन यदि मैं बाद में अपने दृश्य में सीधे एक छिपे हुए पैनल की दृश्यता के साथ झुकाव का फैसला करता हूं, जो ViewModel में पास INotification इंटरफ़ेस के साथ बहुत अच्छी तरह से जाल नहीं करेगा)।

तो मैं के लिए त्वरित और गंदी चला गया:

ViewModel एक string NotificationMessage संपत्ति, PropertyChanged को अधिसूचित परिवर्तन के साथ है।

व्यू PropertyChanged पर सदस्यता लेता है, और यदि यह NotificationMessage संपत्ति को देखता है, तो जो कुछ भी चाहता है वह करता है।

ठीक है, तो इसका मतलब है कि दृश्य में कोड-पीछे है, और PropertyChanged का नाम हार्ड-कोड किया गया है, लेकिन यह XAML में किसी भी तरह से हार्ड-कोड किया जाएगा। और इसका मतलब है कि मैं दृश्यता के लिए कन्वर्टर्स जैसी सभी चीजों से बचता हूं, और गुण यह कहने के लिए कि अधिसूचना अभी भी दिखाई दे रही है या नहीं।

(वैसे यह एक सीमित यूज-केस (आग के लिए सिर्फ और भूल जाते हैं), मैं नहीं दिया है मैं इसे कैसे विस्तार करने के लिए चाहते हो सकता है पर बहुत विचार।)

0

मैं हाल ही में इस समस्या में आए, जहां मैं MessageBox को प्रतिस्थापित करना था। कुछ पूरी तरह से एमवीवीएम शिकायत संदेश बॉक्स तंत्र के साथ ViewModels में दिखाएं।

इसे प्राप्त करने के लिए मैंने InteractionRequest<Notification> और InteractionRequest<Confirmation> का उपयोग इंटरैक्शन ट्रिगर के साथ किया और संदेश बॉक्स के लिए अपना स्वयं का दृश्य लिखा।

मैं क्या क्रियान्वित किया है प्रकाशित किया जाता है here

3

अब डीन चाक के जवाब पर विस्तार करने के लिए है कि उनके लिंक kaput है:

App.xaml.cs हम viewmodel करने के लिए की पुष्टि करें संवाद को हुक फ़ाइल ।

protected override void OnStartup(StartupEventArgs e) 
{ 
    base.OnStartup(e); 
    var confirm = (Func<string, string, bool>)((msg, capt) => MessageBox.Show(msg, capt, MessageBoxButton.YesNo) == MessageBoxResult.Yes); 
    var window = new MainWindowView(); 
    var viewModel = new MainWindowViewModel(confirm); 
    window.DataContext = viewModel; 
    ... 
} 

दृश्य (MainWindowView.xaml) हम एक बटन है कि ViewModel

<Button Command="{Binding Path=DeleteCommand}" /> 

viewmodel (MainWindowViewModel.cs) में एक आदेश कहता है में दिखाने "के लिए एक प्रतिनिधि आदेश का उपयोग करता है क्या आपको यकीन है?" संवाद और कार्रवाई करें। इस उदाहरण में यह SimpleCommandthis जैसा है, लेकिन आईसीओएमएंड के किसी भी कार्यान्वयन को करना चाहिए।

private readonly Func<string, string, bool> _confirm; 

//constructor 
public MainWindowViewModel(Func<string, string, bool> confirm) 
{ 
    _confirm = confirm; 
    ... 
} 

#region Delete Command 
private SimpleCommand _deleteCommand; 
public ICommand DeleteCommand 
{ 
    get { return _deleteCommand ?? (_deleteCommand = new SimpleCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand)); } 
} 

public bool CanExecuteDeleteCommand() 
{ 
    //put your logic here whether to allow deletes 
    return true; 
} 

public void ExecuteDeleteCommand() 
{ 
    bool doDelete =_confirm("Are you sure?", "Confirm Delete"); 
    if (doDelete) 
    { 
     //delete from database 
     ... 
    } 
} 
#endregion 
संबंधित मुद्दे

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