2011-01-04 16 views
5

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

उदाहरण के लिए, यदि आपने PersonViewModel पर व्यवसाय संपत्ति को बदल दिया है, तो यह व्यक्ति व्यक्ति मॉडल में व्यवसाय संपत्ति में कैसे बदल जाता है।

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

internal class PersonViewModel : INotifyPropertyChanged 
{ 
    private readonly PersonModel person; 

    private OccupationViewModel occupation; 

    public PersonViewModel(PersonModel person) 
    { 
     this.person = person; 
    } 

    public OccupationViewModel Occupation 
    { 
     get { return this.occupation; } 
     set 
     { 
      if (!this.occupation.Equals(value)) 
      { 
       this.occupation = value; 
       this.person.Occupation = this.occupation.Occupation; // Doesn't seem right 

       this.OnPropertyChanged(new PropertyChangedEventArgs("Occupation")); 
      } 
     } 
    } 
} 

internal class OccupationViewModel : INotifyPropertyChanged 
{ 
    public OccupationViewModel(OccupationModel occupation) 
    { 
     this.Occupation = occupation; 
    } 

    public OccupationModel Occupation { get; set; } // Is this right? 
} 

internal class PersonModel 
{ 
    public OccupationModel Occupation { get; set; } 
} 
+0

PersonViewModel क्यों है। एक लिखने योग्य संपत्ति का निष्पादन? आम तौर पर यह केवल पढ़ने के लिए होगा - आखिरकार, इसे सेट करने वाला कौन है? –

+0

मैं इसे उजागर करने की सोच रहा था ताकि कुछ अन्य दृश्य मॉडल इसे बदल सकें। या यह वह जगह है जहां कुछ विधि या आदेश आते हैं? बीटीडब्ल्यू, मैं एक डब्ल्यूपीएफ, एमवीवीएम नौसिखिया हूँ। – Patrick

+0

पैट्रिक मुझे लगता है कि जो कह रहा है कि व्यू-मॉडल को इसे बिना सेट किए (बाहरी रूप से एक्सेस करके) को संशोधित किया जा सकता है: 'personViewModel.Occupation.Occupation = new OccationModel (" सॉफ़्टवेयर इंजीनियर ");' – Jay

उत्तर

6

आपके व्यू-मॉडल देखने से मॉडल decoupling है। ऐसा लगता है कि आप दृश्य और दृश्य-मॉडल की अवधारणाओं को भ्रमित कर सकते हैं।

व्यू-मॉडल दोनों के बीच गेटवे और द्वारपाल दोनों है - यह निर्धारित करता है कि मॉडल से दृश्य में और दृश्य से वापस मॉडल तक और किस रूप में।

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

व्यू-मॉडल मॉडल को गहराई से जान सकता है, इसलिए दृश्य को यह बिल्कुल नहीं पता है।

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

+0

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

+0

@ पैट्रिक सरल, सीधा अनुप्रयोगों में, कभी-कभी मॉडल को बेनकाब करने के लिए फायदेमंद होता है। यदि आप जटिलता के साथ काम कर रहे हैं तो हां, दृश्य-मॉडल पर गुणों के माध्यम से आप जो कुछ भी दिखाना चाहते हैं उसे रिले करना सबसे अच्छा है। जब भी आप संरचना से निपट रहे हों, यह ऑब्जेक्ट उन्मुख सिद्धांत के रूप में अधिक आम है। उत्कृष्ट उदाहरणों के लिए – Jay

0

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

व्यक्ति की संपत्ति नीचे की तरह कुछ दिखाई देगी और व्यवसाय की संपत्ति को इस 'viewModel.Person.Occupation' जैसी किसी चीज़ द्वारा संदर्भित किया जा सकता है।

 public Person Person 
    { 
     get 
     { 
      return this.person; 
     } 
     set 
     { 
      if (!this.person.Equals(value)) 
      { 
       this.person = value; 
       this.OnPropertyChanged(new PropertyChangedEventArgs("Person")); 
      } 
     } 
    } 
5

मॉडल और ViewModel के बीच संभावित संबंध दिखाती हैं मैं पहली बार string में Occupation के प्रकार बदल कर अपनी उदाहरण सरलीकृत करने के लिए। तब PersonModel और PersonViewModel इस प्रकार दिखाई देंगे:

public class PersonModel : INotifyPropertyChanged 
{ 
    private string occupation; 
    public string Occupation 
    { 
    get 
    { 
     return this.occupation; 
    } 
    set 
    { 
     if (this.occupation != value) 
     { 
     this.occupation = value; 
     this.OnPropertyChanged("Occupation"); 
     } 
    } 
    } 
} 

public class PersonViewModel: INotifyPropertyChanged 
{ 
    private PersonModel model; 

    public string Occupation 
    { 
    get 
    { 
     return this.model.Occupation; 
    } 
    set 
    { 
     this.model.Occupation = value; 
    } 
    } 

    public PersonViewModel(PersonModel model) 
    { 
    this.model = model; 
    this.model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged); 
    } 

    private void model_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
    this.OnPropertyChanged(e.PropertyName); 
    } 
} 

अपने संस्करण के लिए महत्वपूर्ण अंतर यह है कि PersonModel और PersonViewModelदोनों लागू INotifyPropertyChanged है। यह महत्वपूर्ण है क्योंकि अन्यथा PersonModel की संपत्ति को सीधे बदलना (यानी PersonViewModel के माध्यम से बिना) दृश्य में कोई प्रभाव नहीं पड़ेगा। यह भी ध्यान दें कि मॉडल से PropertyChangedEvent को दृश्य में कैसे पाइप किया गया है।

अब मान लीजिए Occupation एक string लेकिन एक अपनी ही है, जैसे के गुणों के साथ श्रेणी नहीं है:

public class OccupationModel : INotifyPropertyChanged 
{ 
    private double salary; 
    public double Salary 
    { 
    get 
    { 
     return this.salary; 
    } 
    set 
    { 
     if (this.salary != value) 
     { 
     this.salary = value; 
     this.OnPropertyChanged("Salary"); 
     } 
    } 
    } 
} 

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

विकल्प 1Occupation के गुणों का पर्दाफाश PersonViewModel में सीधे: यहाँ दो विकल्प आप इसे कैसे कर सकता है कर रहे हैं। यह एक आसान समाधान है क्योंकि आपको किसी अन्य व्यूमोडेल को लागू करने की आवश्यकता नहीं है।

public class PersonViewModel: INotifyPropertyChanged 
{ 
    private PersonModel model; 

    public double OccupationSalary 
    { 
    get 
    { 
     return this.model.Occupation.Salary; 
    } 
    set 
    { 
     this.model.Occupation.Salary = value; 
    } 
    } 

    public PersonViewModel(PersonModel model) 
    { 
    this.model = model; 
    this.model.Occupation.PropertyChanged += new PropertyChangedEventHandler(occupation_PropertyChanged); 
    } 

    private void occupation_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
    this.OnPropertyChanged("Occupation" + e.PropertyName); 
    } 
} 

OccupationSalary संपत्ति Occupation में Salary संपत्ति के लिए सीधी पहुँच देता है। ध्यान दें कि अब Occupation की घटना को संभालने की आवश्यकता है, और हमें occupation_PropertyChanged में संपत्ति का नाम बदलना होगा।

विकल्प 2 (अनुशंसित) एक OccupationViewModel के माध्यम से Occupation के गुणों बताएं। आपको यह करना चाहिए यदि आपको किसी भी व्यावसायिक तर्क को Occupation पर लागू करने की आवश्यकता है। आप देख सकते हैं OccupationViewModel बिल्कुल उसी संरचना सरलीकृत PersonViewModel जैसा कि मैंने शुरू में पता चला है

public class PersonViewModel: INotifyPropertyChanged 
{ 
    private PersonModel model; 
    private OccupationViewModel occupationViewModel; 
    public OccupationViewModel OccupationViewModel 
    { 
    get 
    { 
     return this.occupationViewModel; 
    } 
    } 

    public PersonViewModel(PersonModel model) 
    { 
    this.model = model; 
    this.occupationViewModel = new OccupationViewModel(this.model.occupation); 
    } 
} 

public class OccupationViewModel : INotifyPropertyChanged 
{ 
    private OccupationModel model; 

    public double Salary 
    { 
    get 
    { 
     return this.model.Salary; 
    } 
    set 
    { 
     this.model.Salary = value; 
    } 
    } 

    public OccupationViewModel(OccupationModel model) 
    { 
    this.model = model; 
    this.model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged); 
    } 

    private void model_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
    this.OnPropertyChanged(e.PropertyName); 
    } 
} 

: अपने उदाहरण को देखते हुए, यह शायद आप क्या करने का इरादा क्या है। OccupationViewModel के आपके संस्करण में महत्वपूर्ण अंतर यह है कि यह गुणOccupationModel का खुलासा करता है, OccupationModel स्वयं नहीं।

+0

उपरोक्त। – bartonm

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