I'm developing a WPF application with MVVM Light Toolkit. I just want to display a nested Observablecollection
which hold the Employee Attendance details into a DataGrid
and do some CRUD functionality in the inner grid and based on those changes I have to automatically recalculate the Outer collection record. The inner collection (PunchDetailModels
) is showing in the RowDetailsTemplate
of the DataGrid
.
Here is the Models :
public class AttendanceModel : ObservableObject
{
public const string EmpNamePropertyName = "EmpName";
private string _empName = string.Empty;
public string EmpName
{
get
{
return _empName;
}
set
{
Set(EmpNamePropertyName, ref _empName, value);
}
}
public const string PunchDetailModelsPropertyName = "PunchDetailModels";
private ObservableCollection<PunchDetailModel> _punchDetailModels = null;
public ObservableCollection<PunchDetailModel> PunchDetailModels
{
get
{
return _punchDetailModels;
}
set
{
Set(PunchDetailModelsPropertyName, ref _punchDetailModels, value);
}
}
private string _inOutCount;
public string InOutCount
{
get
{
return PunchDetailModels != null
? string.Format("{0}/{1}", PunchDetailModels.Count(i => i.PunchStatus == Enums.PunchType.CheckIn),
PunchDetailModels.Count(i => i.PunchStatus == Enums.PunchType.CheckOut))
: null;
}
}
public TimeSpan? FirstCheckIn
{
get
{
if (_punchDetailModels != null)
{
var firstCheckIn =
_punchDetailModels.OrderBy(t => t.PunchTime)
.FirstOrDefault(i => i.PunchStatus == Enums.PunchType.CheckIn);
if (firstCheckIn != null)
return firstCheckIn.PunchTime;
}
return null;
}
}
public TimeSpan? LastCheckOut
{
get
{
if (_punchDetailModels != null)
{
var lastCheckOut =
_punchDetailModels.OrderBy(t => t.PunchTime)
.LastOrDefault(o => o.PunchStatus == Enums.PunchType.CheckOut);
if (lastCheckOut != null)
return lastCheckOut.PunchTime;
}
return null;
}
}
public TimeSpan? TotalInTime
{
get
{
TimeSpan totalInTime = TimeSpan.Zero;
if (_punchDetailModels != null)
{
if (!IsValidRecord()) return null;
for (int inTime = 0; inTime < _punchDetailModels.Count; inTime += 2)
{
totalInTime += _punchDetailModels[inTime + 1].PunchTime - _punchDetailModels[inTime].PunchTime;
}
}
return totalInTime;
}
}
public TimeSpan? TotalOutTime
{
get
{
TimeSpan totalInTime = TimeSpan.Zero;
if (_punchDetailModels != null)
{
if (!IsValidRecord()) return null;
for (int inTime = 1; inTime < _punchDetailModels.Count - 1; inTime += 2)
{
totalInTime += _punchDetailModels[inTime + 1].PunchTime - _punchDetailModels[inTime].PunchTime;
}
}
return totalInTime;
}
}
}
public class PunchDetailModel : ObservableObject
{
public const string PunchStatusPropertyName = "PunchStatus";
private Enums.PunchType _punchStatus;
public Enums.PunchType PunchStatus
{
get
{
return _punchStatus;
}
set
{
Set(PunchStatusPropertyName, ref _punchStatus, value);
}
}
public const string PunchTimePropertyName = "PunchTime";
private TimeSpan _punchTime = TimeSpan.Zero;
public TimeSpan PunchTime
{
get
{
return _punchTime;
}
set
{
Set(PunchTimePropertyName, ref _punchTime, value);
}
}
}
ViewModel :
public const string AttendanceCollectionPropertyName = "AttendanceCollection";
private ObservableCollection<AttendanceModel> _attendanceCollection = null;
public ObservableCollection<AttendanceModel> AttendanceCollection
{
get
{
if (_attendanceCollection == null)
{
_attendanceCollection = new ObservableCollection<AttendanceModel>();
//_attendanceCollection.CollectionChanged+=_attendanceCollection_CollectionChanged;
}
return _attendanceCollection;
}
set
{
Set(AttendanceCollectionPropertyName, ref _attendanceCollection, value);
}
}
View :
Issues I'm facing :
1) When a user ADD or DELETE a particular record from Inner DataGrid, I need to get notification in the View Model. I know it's possible by registering a collection changed event for an ObservableCollection. But how it's possible for an inner ObservableCollection
?
2) I need to get notifications in the viewmodel for any change in CheckIn or Checkout field in the Inner DataGrid, so that I can recalucate fields like TotalInTime, TotalOutTime etc.
How can I do this ? I'm currently stuck with this scenario. Please suggest your valuable points.