ItemPropertyChanged no funciona en observableCollection.Why?

He buscado una solución alta y baja, pero parece que no llego al fondo. Al igual que muchas publicaciones en la red, parece que no hago funcionar mi itemPropertyChanged. No se dispara al editar un elemento en la colección. ¿Por qué?

un poco largo, pero este es un ejemplo que he reunido.

Tengo un customerViewModel que contiene una colección de OrderViewModels al editar el orden en la cuadrícula de datos donde el evento no se activa.

Implementé lo siguiente, pero nunca me despiden cuando edito solo al cargar. Como si no fuera la misma colección de algo …

INotifyPropertyChanged inpc = OrderViewModels; inpc.PropertyChanged += OnItemPropertyChanged; 

¿Alguna sugerencia? Me está volviendo loco

Modelos

 public class Order { public int Id { get; set; } public string Description { get; set; } public int CustomerId{ get; set; } } public class Customer { public Customer() { Orders=new ObservableCollection(); } public int Id { get; set; } public string Name { get; set; } public string Surname{ get; set;} public ObservableCollection Orders{ get; set;} } 

ViewModels

 public class CustomerViewModel : ViewModelBase { private Customer _customerModel; public CustomerViewModel(Customer customerModel) { _customerModel = customerModel; _orderViewModels = new ObservableCollection(); OrderViewModels.CollectionChanged += OnOrdersCollectionChanged; INotifyPropertyChanged inpc = OrderViewModels; inpc.PropertyChanged += OnItemPropertyChanged; } private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e) { //not firing!!!!!!!!!!!!!!!!!!!!!!!!! } void OnOrdersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: _customerModel.Orders.Insert(e.NewStartingIndex, ((OrderViewModel)e.NewItems[0]).OrderModel); break; case NotifyCollectionChangedAction.Remove: _customerModel.Orders.RemoveAt(e.OldStartingIndex); break; case NotifyCollectionChangedAction.Replace: _customerModel.Orders[e.OldStartingIndex] = ((OrderViewModel)e.NewItems[0]).OrderModel; break; case NotifyCollectionChangedAction.Move: _customerModel.Orders.Move(e.OldStartingIndex, e.NewStartingIndex); break; default: throw new ArgumentOutOfRangeException(); } } public int Id { get { return _customerModel.Id; } set { _customerModel.Id = value; OnPropertyChanged("Id"); } } public string Name { get { return _customerModel.Name; } set { _customerModel.Name = value; OnPropertyChanged("Name"); } } public string Surname { get { return _customerModel.Surname; } set { _customerModel.Surname = value; OnPropertyChanged("Surname"); } } public Customer CustomerModel { get { return _customerModel; } set { _customerModel = value; OnPropertyChanged(""); } } private ObservableCollection _orderViewModels; public ObservableCollection OrderViewModels { get { return _orderViewModels; } set { _orderViewModels = value; OnPropertyChanged("OrderViewModels"); } } } public class OrderViewModel:ViewModelBase { private Order _orderModel; public OrderViewModel(Order orderModel) { _orderModel = orderModel; } public int Id { get { return _orderModel.Id; } set { _orderModel.Id = value; OnPropertyChanged("Id"); } } public int CustomerId { get { return _orderModel.CustomerId; } set { _orderModel.CustomerId = value; OnPropertyChanged("CustomerId"); } } public string Description { get { return _orderModel.Description; } set { _orderModel.Description = value; OnPropertyChanged("Description"); } } public Order OrderModel { get { return _orderModel; } set { _orderModel = value; OnPropertyChanged(""); } } } 

Repositorio

 public class OrderRepository { public static ObservableCollection GetOrders(int customerId) { return new ObservableCollection { new Order {Id = 1, CustomerId=1, Description = "MotherBoard"}, new Order {Id = 2, CustomerId=1,Description = "Video Card"}, new Order {Id = 3, CustomerId=1,Description = "TV"}, new Order {Id = 4, CustomerId=1, Description = "Video Recorder"}, new Order {Id = 5, CustomerId=1,Description = "Speakers"}, new Order {Id = 6, CustomerId=1,Description = "Computer"} }; } } 

Ver

 public partial class OrdersView { public OrdersView() { InitializeComponent(); if (!DesignerProperties.GetIsInDesignMode(this)) { var customerVm = new CustomerViewModel(new Customer { Id = 1, Name = "Jo", Surname = "Bloggs" }); var orders = OrderRepository.GetOrders(1); foreach (var orderModel in orders) { customerVm.OrderViewModels.Add(new OrderViewModel(orderModel)); } DataContext = customerVm; } } } 

Xaml

          

  INotifyPropertyChanged inpc = OrderViewModels; inpc.PropertyChanged += OnItemPropertyChanged; 

Ese código le notificará cuando cualquier propiedad en el ObservableCollection cambie, no cuando los elementos en el ObservableCollection tengan sus propiedades modificadas . Por ejemplo, debe llamarse a su controlador cuando agrega o elimina un OrderViewModel porque la propiedad Count cambiará en el ObservableCollection .

Nada está propagando el evento PropertyChanged dentro de OrderViewModel y agregándolos en un solo evento para usted. Utilizo una clase que llamé ItemObservableCollection cuando quiero hacer esto:

 public sealed class ItemObservableCollection : ObservableCollection where T : INotifyPropertyChanged { public event EventHandler> ItemPropertyChanged; protected override void InsertItem(int index, T item) { base.InsertItem(index, item); item.PropertyChanged += item_PropertyChanged; } protected override void RemoveItem(int index) { var item= this[index]; base.RemoveItem(index); item.PropertyChanged -= item_PropertyChanged; } protected override void ClearItems() { foreach (var item in this) { item.PropertyChanged -= item_PropertyChanged; } base.ClearItems(); } protected override void SetItem(int index, T item) { var oldItem = this[index]; oldItem.PropertyChanged -= item_PropertyChanged; base.SetItem(index, item); item.PropertyChanged += item_PropertyChanged; } private void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { OnItemPropertyChanged((T)sender, e.PropertyName); } private void OnItemPropertyChanged(T item, string propertyName) { var handler = this.ItemPropertyChanged; if (handler != null) { handler(this, new ItemPropertyChangedEventArgs(item, propertyName)); } } } public sealed class ItemPropertyChangedEventArgs : EventArgs { private readonly T _item; private readonly string _propertyName; public ItemPropertyChangedEventArgs(T item, string propertyName) { _item = item; _propertyName = propertyName; } public T Item { get { return _item; } } public string PropertyName { get { return _propertyName; } } } 

Puedo usarlo así:

 var orders = new ItemObservableCollection(); orders.CollectionChanged += OnOrdersChanged; orders.ItemPropertyChanged += OnOrderChanged; 

System.ComponentModel.BindingList ofrece la misma funcionalidad que ObservableCollection y maneja los eventos PropertyChanged correctamente.

Atentamente