2009-05-05 16 views
8

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

यहाँ एक उदाहरण नीचे dumbed

वर्ग परिभाषाओं (मान लेते हैं कि मैं ParentViewModel में Child.PropertyChanged घटना झुका है) है:

public class ParentViewModel : ViewModelBase 
{ 
    public ChildViewModel Child { get; set; } 
} 

public class ChildViewModel : ViewModelBase 
{ 
    String _FirstName; 
    public String FirstName 
    { 
     get { return _FirstName; } 
     set 
     { 
      _FirstName = value; 
      OnPropertyChanged("FirstName"); 
     } 
    } 
} 

यहाँ तुम क्या संसाधन शब्दकोश में देखते हैं

<DataTemplate DataType="{x:Type vm:ParentViewModel}"> 
    <vw:ParentView/> 
</DataTemplate> 

<DataTemplate DataType="{x:Type vm:ChildViewModel}"> 
    <vw:ChildView/> 
</DataTemplate> 

और ChildView का कोड-पीछे:

public partial class ChildView : UserControl 
{ 
    public QueueView() 
    { 
     InitializeComponent(); 
     DataContext = new ChildViewModel(); 
    } 
} 

स्पष्ट समस्या यह है कि जब चाइल्डव्यू तत्काल हो जाता है (डेटा टेम्पलेट से चयन के माध्यम से) यह एक नया ChildViewModel क्लास बनाता है और ParentViewModel तक इसका उपयोग नहीं होता है।

तो मैं व्यू के डेटा कॉन्टेक्स्ट को मूल व्यूमोडेल कैसे चालू कर सकता हूं जिससे डेटा टेम्पलेट का चयन किया जा सके?

एक स्पष्ट फिक्स है कि ChildViewModel में गुणों को ParentViewModel में मिलाएं, लेकिन मैं इसे फिर से उपयोग करने के लिए अलग कर दूंगा।

मुझे यकीन है कि उत्तर छोटा है, मैं बस यह जानना चाहता हूं कि यह क्या है। :)

अग्रिम धन्यवाद।

DataContext = new ChildViewModel(); 

देखने के DataContext स्वचालित रूप से WPF द्वारा निर्धारित किया जाएगा:

+0

वैसे, मुझे लगता है कि आपने उदाहरण को सरल बनाने के लिए अपनी कक्षाओं के नाम बदल दिए हैं ... इसके पीछे कोड में "चाइल्ड व्यू" के लिए वर्ग का नाम "क्यूई व्यू" है। –

+0

क्या यह एक टाइपो था? –

+0

हां यह एक टाइपो था। क्षमा करें :) – Jose

उत्तर

8

आप बस लाइन निकाल देना चाहिए। DataTemplates हमेशा अपने डेटा संदर्भ टेम्पलेट के लिए आंकड़ों के निर्धारित किया है (इस मामले ViewModel में):

<DataTemplate DataType="{x:Type vm:ChildViewModel}"> 
    <vw:ChildView/> 
</DataTemplate> 

अंतिम परिणाम है कि आप अपने दृश्य मॉडल अलग से (दोनों माता पिता और बच्चे के वर्ग) और फिर वस्तुओं का निर्माण कर सकते है उन्हें बाद में सामग्री नियंत्रण में प्लग करके उन्हें प्रदर्शित करें।

+0

यदि कोई चाइल्ड व्यू के लिए एक पेरेंट व्यू के लिए इरादा है, तो यह अकेले कैसे बालव्यू के डेटाकॉन्टेक्स्ट को ParentViewModel.Child होने के लिए सेट करता है? –

+0

वैसे परिदृश्य शायद इस तरह कुछ दिखाई देगा: किसी कारखाने या निर्माता विधि में, आप अभिभावक और बाल वस्तु बनायेंगे। यह वस्तु एक दृश्य को सौंपी जाएगी। –

+0

दृश्य या तो माता-पिता को एक सामग्री नियंत्रण और बच्चे को दूसरे में प्रदर्शित करेगा, या यह हेड्रेडकंटेंट नियंत्रण में माता-पिता और बच्चे दोनों को प्रदर्शित करेगा। –

1

मान लें कि आपके पास एक QueueView है जो QueueViewModel का उपयोग करता है।

public class QueueViewModel : INotifyPropertyChanged 
{ 
    public ParentType Parent { get; set; } 

    public QueueViewModel(ParentType parent) 
    { 
     this.Parent = parent; 
     foreach (ChildType child in Parent) 
     { 
      child.PropertyChanged += delegate(object sender, 
       PropertyChangedEventArgs e) 
      { 
       if (e.PropertyName != "IsSelected") 
        return; 

       //do something like this: 
       Parent.IsSelected = AllChildrenAreSelected(); 
      }; 
     } 
    } 

} 

public class ParentType : INotifyPropertyChanged 
{ 
    private bool _isSelected; 

    public IList<ChildType> Children { get; set; } 
    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set 
     { 
      _isSelected = value; 
      OnPropertyChanged("IsSelected"); 
     } 
    } 
} 

public class ChildType : INotifyPropertyChanged 
{ 
    private string _name; 
    private bool _isSelected; 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      _name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 

    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set 
     { 
      _isSelected = value; 
      OnPropertyChanged("IsSelected"); 
     } 
    } 
} 

- QueueView हिस्सा

<StackPanel> 
<CheckBlock Text="{Binding Path=Parent.Name}" 
      IsChecked="{Binding Parent.IsSelected}"/> 
<ItemsControl ItemsSource="{Binding Path=Parent.Children}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate>          
      <CheckBox Content="{Binding Path=Name}" 
         IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/> 
     </DataTemplate> 
    <ItemsControl.ItemTemplate> 
</ItemsControl> 
</StackPanel> 
+0

आपके कोड नमूने वास्तव में प्रश्न से संबंधित नहीं लगते हैं। क्या हम में से एक या दोनों ने इस बिंदु को याद किया? –

+0

मैं मान रहा था कि चाइल्ड मॉडल माता-पिता मॉडल की एक संपत्ति थी। (उदा। ऑर्डर + ऑर्डर विवरण की सूची)। इस मामले में आप व्यू मॉडल के भीतर संवाद करने के लिए प्रॉपर्टी-चेंज नोटिफिकेशन का उपयोग कर सकते हैं। लेकिन अगर वे अलग-अलग दृश्य मॉडल हैं, तो आप संवाद करने के लिए मध्यस्थ पैटर्न का उपयोग कर सकते हैं। –

5

MVVM दृष्टिकोण का उपयोग कर ViewModels के बीच संवाद का सबसे आसान तरीका मध्यस्थ पैटर्न (प्रिज्म में EventAggregator) का प्रयोग है। इस दृष्टिकोण का एक अच्छा उदाहरण निम्नलिखित लिंक में देखा जा सकता:

  1. MVVM Mediator Pattern by Sacha Barber
  2. MVVM + Mediator by marlon grech

इसके अलावा MVVM sample परियोजना ढांचे की जाँच करें।

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