我的问题与MVVM in WPF - How to alert ViewModel of changes in Model... or should I?和ViewModel subscribing to Model's PropertyChanged event for a specific property非常相似。然而,这是有区别的。
背景资讯
我的模型是员工,我感兴趣的属性是DisplayLtdOccupationId。
但在我的ViewModel中,我不只是拥有一个Employee实例。相反,我有一组Employee对象。
ObservableCollection<Employee> EmployeeCensus
在我的视图中,我有一个绑定到EmployeeCensus的DataGrid。所以我在网格中有Employee行。
问题
我想要的是能够响应DisplayLtdOccupationId值更改的特定Employee行的PropertyChanged。我想在我的ViewModel中使用处理程序方法执行此操作。
在我的处理程序中,我希望刚刚更改的Employee对象位于'sender'变量中。然后我将使用它的DisplayLtdOccupationId,从我在ViewModel的内存中已经拥有的集合中进行查找,并将查找值设置在同一个Employee对象的不同属性中。
更多详情
ViewModel和Employee Model都实现了INotifyPropertyChanged(通过:Microsoft.Practices.Prism.ViewModel.NotificationObject)。
DataGrid将DisplayLtdOccupationId属性显示为内联下拉列表,用户可以在其中选择不同的值。
为什么不在员工模型中,在SetL of DisplayLtdOccupationId中执行此操作?因为我无权访问那里的查找集合。
我不想在视图中使用触发器来启动处理程序。这导致了一个问题,这也是我想要使用ViewModel和Model仅探索解决方案的原因。
我可以添加更多内容,但我正在尝试将问题简明扼要。如果需要更多信息,请告知。
答案 0 :(得分:1)
像这样的东西。我想你会希望得到一些更聪明,更简洁的东西,但这就是你得到的。 Employee_PropertyChanged
处理Employee
属性的更改。您还可以为Employee
课程提供针对其DisplayLtdOccupationId
媒体资源的更改所引发的特定事件。然后您的父视图模型将处理该事件而不是PropertyChanged
。无论哪种方式都有效。
public class ViewModel : ViewModelBase
{
public ViewModel()
{
EmployeeCensus = new ObservableCollection<Employee>();
}
#region EmployeeCensus Property
private ObservableCollection<Employee> _employeeCensus = null;
public ObservableCollection<Employee> EmployeeCensus
{
get { return _employeeCensus; }
// Protect this so we don't have to handle the case of somebody giving us
// a whole new collection of new Employees.
protected set
{
if (value != _employeeCensus)
{
if (_employeeCensus != null)
{
_employeeCensus.CollectionChanged -= _employeeCensus_CollectionChanged;
}
_employeeCensus = value;
OnPropertyChanged(nameof(EmployeeCensus));
if (_employeeCensus != null)
{
_employeeCensus.CollectionChanged += _employeeCensus_CollectionChanged;
}
}
}
}
private void _employeeCensus_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var item in e.OldItems.Cast<Employee>())
{
item.PropertyChanged -= Employee_PropertyChanged;
}
}
if (e.NewItems != null)
{
foreach (var item in e.NewItems.Cast<Employee>())
{
item.PropertyChanged += Employee_PropertyChanged;
}
}
}
private void Employee_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(Employee.DisplayLtdOccupationId):
// Do stuff
break;
}
}
#endregion EmployeeCensus Property
}