c# wpf mvvm viewmodel datacontext

c# - Patrón MVVM, pregunta de ViewModel DataContext



wpf (3)

Digamos que tiene un QueueView que usa un 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"); } } }

- Parte 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>

Necesito descubrir cómo comunicarme entre ViewModels. Soy nuevo en MVVM así que sea amable.

Aquí hay un ejemplo tonto

definiciones de clases (supongamos que he enlazado el evento Child.PropertyChanged en ParentViewModel):

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"); } } }

Esto es lo que ve en el diccionario de recursos

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

y el código subyacente de ChildView:

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

El problema obvio es que cuando se crea una instancia de ChildView (a través de la selección de DataTemplate) se crea una nueva clase ChildViewModel y ParentViewModel no tiene acceso a ella.

Entonces, ¿cómo puedo instanciar el DataContext de la Vista para que sea el ViewModel original que hizo que se seleccionara DataTemplate?

Una solución obvia es fusionar las propiedades en el modelo ChildViewModel en ParentViewModel, pero prefiero separarlo para su reutilización.

Estoy seguro de que la respuesta es trivial, solo me gustaría saber de qué se trata. :)

Gracias por adelantado.


Simplemente debes eliminar la línea:

DataContext = new ChildViewModel();

El DataContext de la vista se establecerá automáticamente por WPF. DataTemplates siempre tiene su contexto de datos establecido en los datos para la plantilla (en este caso, el ViewModel):

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

El resultado final es que puede compilar los objetos del modelo de vista por separado (clases principales y secundarias) y luego mostrarlos más tarde simplemente conectándolos a controles de contenido.