2010-10-04 5 views
12

मैं एक दृश्य में एक बटन, ViewModel के ICommand संपत्ति के लिए बाध्यनेविगेशन तर्क कहां से संबंधित है, देखें, ViewModel, या कहीं और?

उपयोगकर्ता बटन मैं एक नया दृश्य पर जाएं, करना चाहते हैं पर क्लिक करता है (वास्तव में यह RelayCommand mvvv-प्रकाश से है)। निस्संदेह NavigationService व्यूमोडेल दृश्य का हिस्सा है। इसका तात्पर्य है कि नेविगेशन दृश्य की ज़िम्मेदारी है? लेकिन मेरे मामले में, जब मैं बटन क्लिक किया जाता हूं तो दृश्य एक बहुत से कारकों पर निर्भर करता है, जिसमें लॉग इन उपयोगकर्ता कौन है, राज्य डेटाबेस है, आदि ... निश्चित रूप से दृश्य को सभी की आवश्यकता नहीं होनी चाहिए वह जानकारी।

NavigationService निष्पादित करने के लिए पसंदीदा विकल्प क्या है। नेविगेट कॉल?

उत्तर

12

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

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

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

public class NavigationMessage : NotificationMessage 
{ 
    public string PageName 
    { 
     get { return base.Notification; } 
    } 

    public Dictionary<string, string> QueryStringParams { get; private set; } 

    public NavigationMessage(string pageName) : base(pageName) { } 

    public NavigationMessage(string pageName, Dictionary<string, string> queryStringParams) : this(pageName) 
    { 
     QueryStringParams = queryStringParams; 
    } 
} 

यह केवल पृष्ठ नाम से गुजर रहा है, या वैकल्पिक रूप से भी किसी भी आवश्यक क्वेरी स्ट्रिंग पैरामीटर शामिल करने के लिए अनुमति देता है।

private void RelayCommandHandler() 
{ 
    //Logic for determining next view, then ... 
    Messenger.Default.Send(new NavigationMessage("ViewToNavigate")); 
} 

अंत में, दृश्य आधार वर्ग इस तरह दिखता है:

public class BasePage : PhoneApplicationPage 
{ 
    public BasePage() 
    { 
     Messenger.Default.Register<NavigationMessage>(this, NavigateToPage); 
    } 

    protected void NavigateToPage(NavigationMessage message) 
    { 
     //GetQueryString isn't shown, but is simply a helper method for formatting the query string from the dictionary 
     string queryStringParams = message.QueryStringParams == null ? "" : GetQueryString(message); 

     string uri = string.Format("/Views/{0}.xaml{1}", message.PageName, queryStringParams); 
     NavigationService.Navigate(new Uri(uri, UriKind.Relative)); 
    } 
} 

यह एक सम्मेलन संभालने जाता है, जहां सभी दृश्यों एक "दृश्य" फ़ोल्डर में हैं एक RelayCommand हैंडलर इस संदेश को इस तरह प्रकाशित करेंगे ऐप की जड़ में। यह हमारे ऐप के लिए ठीक काम करता है लेकिन निश्चित रूप से यह आपके विचारों को व्यवस्थित करने के लिए विभिन्न परिदृश्यों का समर्थन करने के लिए बढ़ाया जा सकता है।

+0

उत्कृष्ट सुझाव, धन्यवाद! –

+0

मैं स्वीकार करूंगा कि मैसेंजर सिस्टम से बहुत परिचित नहीं हूं कि एमवीवीएम-लाइट ऑफर करता है। आगे प्रतिबिंब पर, क्या इसका मतलब यह नहीं है कि सभी विचार इस नेविगेशन मैसेज के लिए पंजीकरण करेंगे और सुनेंगे? –

+0

मुझे लगता है कि यह एक मुद्दा हो सकता है। मैं इस तकनीक का उपयोग विंडोज फोन 7 ऐप के संदर्भ में कर रहा हूं जहां मेरे पास एक समय में केवल एक दृश्य सक्रिय है, इसलिए यह पूरी तरह से अच्छी तरह से काम करता है। यदि आप सिल्वरलाइट, या डब्ल्यूपीएफ के डेस्कटॉप संस्करण में काम कर रहे हैं, और आपके पास एक बार में कई दृश्य सक्रिय हैं, तो मैं देख सकता हूं कि यह समस्या कहां हो सकती है। इसके बारे में कुछ और सोचना होगा। –

6

चेतावनी: स्वच्छंद MVVM नौसिखिया चेतावनी :) (मैं बहुत MVVM करने के लिए नए कर रहा हूँ, लेकिन यह एक बहुत अब तक का आनंद ले।)

अच्छा प्रश्न है। मैंने पाया है कि यह NavigationService पर नकल करने के लिए पूरी तरह से व्यवहार्य (यदि स्थानों में थोड़ा बदसूरत है) और एक ViewModel में INavigationService पास करें। वास्तव में, आप एक स्ट्रिंग यूआरआई की बजाय टाइप (एक प्रकार तर्क के रूप में) में पास करने के लिए जेनेरिक के साथ इंटरफ़ेस को थोड़ा सा भी कर सकते हैं।

हालांकि, मैंने पाया मैं कुछ हद तक unstuck जब यह जिसमें आप नेविगेशन में शामिल अतिरिक्त डेटा डाल करने के लिए आता है आए हैं ... मैं प्रचार करने के लिए सभी एन्कोडिंग/unencoding करने के लिए एक अच्छा ही स्थान नहीं मिला है अच्छी तरह से राज्य। मुझे संदेह है कि ViewModelFactory अच्छी तरह से उस समीकरण का हिस्सा हो सकता है ...

तो, अभी तक एक सही समाधान नहीं है - लेकिन कम से कम ViewModel "नेविगेट अब" (या "वापस जाएं") की कार्रवाई के लिए ज़िम्मेदार हो सकता है।

+0

मैं भी एमवीवीएम का आनंद ले रहा हूं, सिल्वरलाइट टेम्पलेट्स के कुछ बिट्स प्रतीत होते हैं जो विशेष रूप से एमवीवीएम अनुकूल नहीं हैं; नेविगेशन एक है।"यूरी" के रूप में एक स्ट्रिंग के बजाय एक प्रकार को पारित करने के विचार के लिए धन्यवाद। जो इस संदर्भ में सही समझ में आता है। –

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