यह एमवीपी और आपके विशिष्ट मुद्दों पर मेरी विनम्रता है।
सबसे पहले , कुछ भी जो उपयोगकर्ता के साथ बातचीत कर सकता है, या बस दिखाया जा सकता है, एक दृश्य है । इस तरह के दृश्य के कानून, व्यवहार और विशेषताओं को एक इंटरफेस द्वारा वर्णित किया गया है । उस इंटरफ़ेस को एक WinForms UI, एक कंसोल UI, एक वेब UI या यहां तक कि कोई भी यूआई (आमतौर पर प्रस्तुतकर्ता का परीक्षण करते समय) का उपयोग करके लागू किया जा सकता है - ठोस कार्यान्वयन सिर्फ तब तक कोई फर्क नहीं पड़ता जब तक कि वह अपने दृश्य इंटरफ़ेस के नियमों का पालन नहीं करता है ।
दूसरा , एक दृश्य हमेशा एक प्रस्तुतकर्ता द्वारा नियंत्रित किया जाता है । इस तरह के एक प्रस्तुतकर्ता के कानून, व्यवहार और विशेषताओं को एक इंटरफेस द्वारा भी वर्णित किया गया है । जब तक वह अपने दृश्य इंटरफ़ेस के नियमों का पालन करता है, तब तक उस इंटरफ़ेस को ठोस दृश्य कार्यान्वयन में कोई रुचि नहीं है।
तीसरा , चूंकि एक प्रस्तुतकर्ता अपने दृष्टिकोण को नियंत्रित करता है, इसलिए निर्भरता को कम करने के लिए वास्तव में इसके प्रस्तुतकर्ता के बारे में कुछ भी जानने के दृश्य होने में कोई लाभ नहीं है। प्रस्तुतकर्ता और दृश्य के बीच एक सहमति अनुबंध है और यह दृश्य इंटरफ़ेस द्वारा कहा गया है।
तीसरे के निहितार्थ हैं:
- प्रस्तुतकर्ता के पास कोई भी तरीका नहीं है जिसे दृश्य कॉल कर सकता है, लेकिन दृश्य में ऐसी घटनाएं हैं जिन्हें प्रस्तुतकर्ता सदस्यता ले सकता है।
- प्रस्तुतकर्ता इसका दृष्टिकोण जानता है। मैं कंक्रीट प्रस्तुतकर्ता पर निर्माता इंजेक्शन के साथ इसे पूरा करना पसंद करता हूं।
- प्रस्तोता के पास इसे नियंत्रित करने के बारे में कोई विचार नहीं है; यह सिर्फ किसी भी प्रस्तुतकर्ता प्रदान नहीं किया जाएगा।
आपके मुद्दे के लिए, ऊपर कुछ हद तक सरलीकृत कोड में इस तरह दिख सकता है:
interface IConfigurationView
{
event EventHandler SelectConfigurationFile;
void SetConfigurationFile(string fullPath);
void Show();
}
class ConfigurationView : IConfigurationView
{
Form form;
Button selectConfigurationFileButton;
Label fullPathLabel;
public event EventHandler SelectConfigurationFile;
public ConfigurationView()
{
this.selectConfigurationFileButton.Click += delegate
{
var Handler = this.SelectConfigurationFile;
if (Handler != null)
{
Handler(this, EventArgs.Empty);
}
};
}
public void SetConfigurationFile(string fullPath)
{
this.fullPathLabel.Text = fullPath;
}
public void Show()
{
this.form.ShowDialog();
}
}
interface IConfigurationPresenter
{
void ShowView();
}
class ConfigurationPresenter : IConfigurationPresenter
{
Configuration configuration = new Configuration();
IConfigurationView view;
public ConfigurationPresenter(IConfigurationView view)
{
this.view = view;
this.view.SelectConfigurationFile += delegate
{
var selectFilePresenter = Gimme.The<ISelectFilePresenter>();
selectFilePresenter.ShowView();
this.configuration.FullPath = selectFilePresenter.FullPath;
this.view.SetConfigurationFile(this.configuration.FullPath);
};
}
public void ShowView()
{
this.view.SetConfigurationFile(this.configuration.FullPath);
this.view.Show();
}
}
उपरोक्त के अतिरिक्त, मेरे पास आमतौर पर एक आधार IView
इंटरफ़ेस होता है जहां मैं स्टैश करता हूंShow()
और किसी भी मालिक के दृश्य या दृश्य शीर्षक को टकराता हूं जिससे मेरे विचार आमतौर पर लाभान्वित होते हैं।
आपके प्रश्नों के लिए:
1. जब विनफॉर्म लोड होता है, तो उसे ट्रीव्यू प्राप्त करना होता है। क्या मैं यह सोचने में सही हूं कि दृश्य को इसलिए एक विधि को कॉल करना चाहिए जैसे: प्रस्तुतकर्ता.गेट्री (), यह बदले में मॉडल को सौंप देगा, जो ट्रीव्यू के लिए डेटा प्राप्त करेगा, इसे बनाएं और इसे कॉन्फ़िगर करें, इसे वापस लौटाएं। प्रस्तुतकर्ता, जो बदले में उस दृश्य को पास करेगा जो तब इसे केवल एक पैनल को कहता है,
मैं कॉल करने IConfigurationView.SetTreeData(...)
से IConfigurationPresenter.ShowView()
ठीक पहले कॉल करूंगाIConfigurationView.Show()
2. क्या यह Winform पर किसी भी डेटा नियंत्रण के लिए समान होगा, क्योंकि मेरे पास एक डेटाग्रिडव्यू भी है?
हां, मैं उसके लिए कॉल करूंगा IConfigurationView.SetTableData(...)
। यह दिए गए डेटा को प्रारूपित करने की दृष्टि पर निर्भर है। प्रस्तुतकर्ता बस दृश्य के अनुबंध का पालन करता है कि वह सारणीबद्ध डेटा चाहता है।
3. माय ऐप, एक ही विधानसभा के साथ कई मॉडल कक्षाएं हैं। यह प्लगइन्स के साथ एक प्लगइन आर्किटेक्चर का भी समर्थन करता है जिसे स्टार्टअप पर लोड करने की आवश्यकता होती है। क्या दृश्य बस एक प्रस्तोता विधि को कॉल करेगा, जो बदले में एक विधि को कॉल करेगा जो प्लगइन्स को लोड करता है और दृश्य में जानकारी प्रदर्शित करता है? फिर कौन सा टियर प्लगइन संदर्भों को नियंत्रित करेगा। क्या दृश्य उनके या प्रस्तुतकर्ता के संदर्भ में होगा?
यदि प्लगइन्स दृश्य-संबंधी हैं, तो विचारों को उनके बारे में जानना चाहिए, लेकिन प्रस्तुतकर्ता नहीं। यदि वे सभी डेटा और मॉडल के बारे में हैं, तो दृश्य को उनके साथ कुछ भी नहीं करना चाहिए।
4. क्या मैं यह सोचने में सही हूं कि दृश्य को प्रेजेंटेशन के बारे में हर एक चीज को ट्रीव्यू नोड कलर से, डेटाग्रिड के आकार, आदि से संभालना चाहिए?
हाँ। इसके बारे में सोचो कि प्रस्तुतकर्ता XML प्रदान करता है जो डेटा का वर्णन करता है और वह दृश्य जो डेटा लेता है और उस पर CSS स्टाइलशीट लागू होता है। ठोस शब्दों में, प्रस्तुतकर्ता कॉल कर सकता है IRoadMapView.SetRoadCondition(RoadCondition.Slippery)
और दृश्य फिर सड़क को लाल रंग में प्रस्तुत करता है।
क्लिक किए गए नोड्स के डेटा के बारे में क्या?
5. यदि मैं ट्रिनोड्स पर क्लिक करता हूं, तो क्या मुझे प्रस्तुतकर्ता के लिए विशिष्ट नोड से गुजरना चाहिए और फिर उस से प्रस्तुतकर्ता काम करेगा कि उसे किस डेटा की आवश्यकता है और फिर उस डेटा के लिए मॉडल पूछता है, इसे दृश्य में वापस प्रस्तुत करने से पहले?
यदि संभव हो तो, मैं पेड़ को एक शॉट में एक दृश्य में प्रस्तुत करने के लिए आवश्यक सभी डेटा पास करूंगा। लेकिन अगर कुछ डेटा को शुरू से ही पास करने के लिए बहुत बड़ा है या अगर यह अपनी प्रकृति में गतिशील है और मॉडल (प्रस्तुतकर्ता के माध्यम से) से "नवीनतम स्नैपशॉट" की आवश्यकता है, तो मैं कुछ इस तरह जोड़ूंगा जैसे event LoadNodeDetailsEventHandler LoadNodeDetails
कि इंटरफ़ेस। प्रस्तुतकर्ता इसे सदस्यता ले सकता है, LoadNodeDetailsEventArgs.Node
मॉडल से नोड का विवरण (संभवत: अपनी आईडी के माध्यम से किसी प्रकार का) प्राप्त कर सकता है, ताकि घटना हैंडलर प्रतिनिधि के वापस आने पर दृश्य इसके दिखाए गए नोड विवरण को अपडेट कर सके। ध्यान दें कि यदि उपयोगकर्ता को अच्छे उपयोगकर्ता अनुभव के लिए डेटा धीमा हो सकता है, तो इसके लिए async पैटर्न की आवश्यकता हो सकती है।