I assume that the ObservableObject class is your own implementation of the INotifyPropertyChanged interface. Now, to solve your problems:
You must register in the CollectionChanged event in _punchDetailModels and raise the PropertyChanged event for this variable in the handler, for example:
public ObservableCollection<PunchDetailModel> PunchDetailModels { get { return _punchDetailModels; } set { Set(PunchDetailModelsPropertyName, ref _punchDetailModels, value); _punchDetailModels.CollectionChanged += handler; } } private void handler(object sender, NotifyCollectionChangedEventArgs e) { base.RaisePropertyChanged(PunchDetailModelsPropertyName);
Therefore, the view should reload automatically when adding or removing items from the internal collection.
There is no other way to subscribe to listen to PropertyChanged in these fields. What View does and what ViewModel should do. For instance:
public const string AttendanceCollectionPropertyName = "AttendanceCollection"; private ObservableCollection<AttendanceModel> _attendanceCollection = null; public ObservableCollection<AttendanceModel> AttendanceCollection { get { if (_attendanceCollection == null) { _attendanceCollection = new ObservableCollection<AttendanceModel>(); } return _attendanceCollection; } set { Set(AttendanceCollectionPropertyName, ref _attendanceCollection, value); _attendanceCollection.CollectionChanged+= handler } } private void handler(object sender, NotifyCollectionChangedEventArgs e) { foreach (AttendanceModel model in AttendanceCollection) model.PropertyChanged += somethingChanged; }
And, of course, you need to raise the PropertyChanged with the string argument to the CheckIn value in the AttendanceModel class if you consider it necessary (for example, in the handler method)
EDIT:
To answer your question:
"Come to the second - I need to recalculate the attendance model properties, such as InOutCount, TotalInTime, TotalOutTime in updating the PunchTime field."
Answer: you do not need to do anything in the ViewModel to "recount". The user interface subscribes to PropertyChange for InOutCount , FirstCheckIn ... and so on. This is due to Binding (it does this automatically).
So, all you have to do to tell the user interface that this model should be recounted is to call RaisePropertyChanged("InOutCount") , RaisePropertyChanged("FirstCheckIn") . The user interface will understand that it needs to GET these properties, and since you have these calculations in the getters properties, it will be recalculated.
So, I see that the UI needs to be recounted every time the INNER list is changed, so all you have to do is change the handler code to CollectionChanged for PunchDetailModels as follows:
// the handler for CollectionChanged for the INNER collection (PunchDetailModels) private void handler(object sender, NotifyCollectionChangedEventArgs e) { base.RaisePropertyChanged(PunchDetailModelsPropertyName); // If you don't have a method with such signature in ObservableObject (one that takes a string and raises PropertyChanged for it) you'll have to write it. base.RaisePropertyChanged("InOutCount") base.RaisePropertyChanged("FirstCheckIn") base.RaisePropertyChanged("LastCheckOut") // and so on for all the properties that need to be refreshed }
source share