WPF MVVM-如何订阅绑定到网格行的模型实例的PropertyChanged?
我的问题与像和这样的问题非常相似。然而,这是有区别的 背景信息 我的模型是Employee,我感兴趣的属性是DisplayLtdOccupationId 但在我的ViewModel中,我不仅仅有Employee的一个实例。相反,我有一个雇员对象的集合WPF MVVM-如何订阅绑定到网格行的模型实例的PropertyChanged?,wpf,mvvm,Wpf,Mvvm,我的问题与像和这样的问题非常相似。然而,这是有区别的 背景信息 我的模型是Employee,我感兴趣的属性是DisplayLtdOccupationId 但在我的ViewModel中,我不仅仅有Employee的一个实例。相反,我有一个雇员对象的集合 ObservableCollection<Employee> EmployeeCensus ObservableCollection员工普查 在我看来,我有一个绑定到EmployeeCensus的数据网格。所以我在网格中有员工行
ObservableCollection<Employee> EmployeeCensus
ObservableCollection员工普查
在我看来,我有一个绑定到EmployeeCensus的数据网格。所以我在网格中有员工行
问题
我希望能够响应DisplayLtdOccupationId值已更改的特定员工行的PropertyChanged。我想用ViewModel中的处理程序方法来实现这一点
在我的处理程序中,我希望刚刚更改的Employee对象将位于“sender”变量中。然后,我将获取它的DisplayLtdOccupationId,从ViewModel内存中已有的集合中进行查找,并在同一Employee对象的不同属性中设置查找值
更多详细信息
ViewModel和Employee模型都实现了INotifyPropertyChanged(通过:Microsoft.Practices.Prism.ViewModel.NotificationObject)
DataGrid将DisplayLtdOccupationId属性显示为一个内联下拉列表,用户可以在其中选择不同的值
为什么不在雇员模型中,在DisplayLtdOccupationId的Setter中这样做呢?因为我没有访问那里的查找集合的权限
我不想在视图中使用触发器来启动处理程序。这导致了一个问题,这也是为什么我想探索仅使用ViewModel和Model的解决方案
我还可以补充更多,但我会尽量让问题简明扼要。如果需要更多信息,请告知。类似的信息。我想你是希望有一个更聪明,更少冗长的东西,但这就是你得到的
Employee\u PropertyChanged
处理对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
}
public类ViewModel:ViewModelBase
{
公共视图模型()
{
EmployeeCensus=新的ObservableCollection();
}
#地区雇员普查财产
私有可观测集合_employeeCensus=null;
公共可观测集合雇员普查
{
获取{return\u employeeCensus;}
//保护好它,这样我们就不必处理有人给我们
//新员工的全新集合。
保护集
{
如果(值!=\u员工普查)
{
如果(_employeeCensus!=null)
{
_employeeCensus.CollectionChanged-=\u employeeCensus\u CollectionChanged;
}
_雇员普查=价值;
财产变更(姓名(员工普查));
如果(_employeeCensus!=null)
{
_employeeCensus.CollectionChanged+=\u employeeCensus\u CollectionChanged;
}
}
}
}
private void\u employeeCensus\u CollectionChanged(对象发送方,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
如果(例如,OldItems!=null)
{
foreach(e.OldItems.Cast()中的变量项)
{
item.PropertyChanged-=员工的财产发生了变化;
}
}
如果(如NewItems!=null)
{
foreach(e.NewItems.Cast()中的变量项)
{
item.PropertyChanged+=员工_PropertyChanged;
}
}
}
私有void Employee_PropertyChanged(对象发送者,PropertyChangedEventArgs e)
{
开关(如PropertyName)
{
案例名称(Employee.DisplayLtdOccupationId):
//做事
打破
}
}
#endregion雇员普查财产
}
哇,真是太快了。让我试试看!我不确定是否必须将处理程序添加到每个实例中,我看到了!感谢为安全起见编写的代码,并删除了处理程序。如果只将OC属性设置为只读,会简单得多。@Will这是真的。'您还可以为员工类提供一个特定的事件,该事件是在其DisplayLtdOccupationId属性发生更改时引发的。'我养成了在我访问的每个属性附近都有这些事件的习惯创建以避免处理属性更改-无论是好是坏。