2009-05-05 31 views
8

ViewModels arasında nasıl iletişim kuracağımı bulmam gerek. Ben MVVM için yeniyim, lütfen nazik ol. İşte MVVM Pattern, ViewModel DataContext soru

bir dumbed ömeği

sınıf tanımları (Ben ParentViewModel içinde Child.PropertyChanged olayı bağımlısı olduğu düşünülerek) var: Burada kaynak sözlükte bakın ne

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> 

ve ChildView'ın arkadaki kodu:

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

Açık olan sorun, ChildView'ın başlatılmasıyla (DataTemplate'den seçim) yeni bir ChildViewModel sınıfı oluşturması ve ParentViewModel'in ona erişimi olmamasıdır.

Peki, DataTemplate'in seçilmesine neden olan özgün ViewModel olmak için Görünümün DataContext'ini nasıl uygulayabilirim?

Açık bir düzeltme, ChildViewModel'deki özellikleri ParentViewModel'e yerleştirmektir, ancak yeniden kullanmak için ayırmak isterim.

Cevabın önemsiz olduğundan eminim, sadece ne olduğunu bilmek istiyorum. :)

Önceden teşekkürler.

DataContext = new ChildViewModel(); 

bakış DataContext WPF tarafından otomatik olarak ayarlanacaktır:

+0

Bu arada, örneği basitleştirmek için sınıflarınızın adlarını değiştirdiğinizi varsayalım. Kodun arkasındaki "ChildView" sınıf adı bunun yerine "QueueView" dır. –

+0

Bu bir yazım hatası mıydı? –

+0

Evet, bu bir yazım hatasıydı. pardon :) – Jose

cevap

8

Sadece çizgiyi kaldırmak gerekir. DataTemplates her zaman kendi veri bağlamı (bu durumda ViewModel olarak) şablon için verilere belirledik:

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

Sonuçta sizin bakış modeli ayrı ayrı (hem üst hem de alt sınıflar) ve daha sonra nesneleri inşa edebilirsiniz olmasıdır Daha sonra bunları içerik denetimlerine bağlayarak görüntüler.

+0

Bir ChildView içerecek şekilde bir ParentView için amaç ise, bu, ChildView DataContext ParentViewModel.Child olarak nasıl ayarlanır? –

+0

Bu senaryo muhtemelen şu gibi bir şeye benzeyecektir: Bir fabrikada veya bir oluşturucu yönteminde, üst ve alt nesne oluşturabilirsiniz. Bu nesne bir görüşe verilecek. –

+0

Görünüm, ebeveyni bir içerik denetiminde ve diğerinde çocukta gösterecek ya da hem ebeveyn hem de çocuğu HeaderedContent denetiminde gösterecektir. –

1

Bir QueueViewModel kullanan bir QueueView'unuz olduğunu varsayalım.

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 parçası

<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

Kod örnekleriniz gerçekten soruyla ilgili görünmüyor. Birimiz mi, yoksa ikimizi de özledik mi? –

+0

Çocuk Modelinin Ana Modelin bir özelliği olduğunu varsayıyordum. (örneğin Sipariş + Sipariş Detayları Listesi). Bu durumda, görünüm modelinde iletişim kurmak için Property-Change bildirimlerini kullanabilirsiniz. Ancak ayrı görünüm modelleri ise, iletişim kurmak için Mediator Kalıbı'nı kullanabilirsiniz. –