using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using SchoolSample.Common;
using SchoolSample.EntityModel;
namespace SchoolSample.ViewModel
{
[Export(ViewModelTypes.CoursePageViewModel, typeof(ViewModelBase))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class CoursePageViewModel : ViewModelBase
{
#region "Private Data Members"
private ISchoolModel _schoolModel;
#endregion "Private Data Members"
#region "Constructor"
[ImportingConstructor]
public CoursePageViewModel(ISchoolModel schoolModel)
{
_schoolModel = schoolModel;
// set up event handling
_schoolModel.PropertyChanged += _schoolModel_PropertyChanged;
_schoolModel.GetStudentsCompleted += _schoolModel_GetStudentsCompleted;
_schoolModel.GetInstructorsCompleted += _schoolModel_GetInstructorsCompleted;
_schoolModel.GetCoursesCompleted += _schoolModel_GetCoursesCompleted;
_schoolModel.GetCourseByIdCompleted += _schoolModel_GetCourseByIdCompleted;
_schoolModel.SaveCourseChangesCompleted += _schoolModel_SaveCourseChangesCompleted;
PropertyChanged += CoursePageViewModel_PropertyChanged;
// get students
_schoolModel.GetStudentsAsync("None", "CoursePage");
// get instructors
_schoolModel.GetInstructorsAsync("None", "CoursePage");
// get courses
_schoolModel.GetCoursesAsync("CoursePage");
// set up initial screen status
CourseFormEndEdit();
EnrollmentFormEndEdit();
}
#endregion "Constructor"
#region "Public Properties"
/// <summary>
/// All courses collection returns/updates CoursesList from _schoolModel,
/// _allCoursesCache keeps a local reference to the list and it syncs with
/// _schoolModel.CoursesList when navigates to this page
/// </summary>
private ObservableCollection<Course> AllCourses
{
get
{
return _schoolModel != null ? _schoolModel.CoursesList : null;
}
set
{
if (!ReferenceEquals(_allCoursesCache, value))
{
_allCoursesCache = value;
// update CoursesList on the model
if (_schoolModel != null) _schoolModel.CoursesList = _allCoursesCache;
}
}
}
private ObservableCollection<Course> _allCoursesCache;
public CollectionViewSource AllCoursesSource
{
get { return _allCoursesSource; }
private set
{
if (!ReferenceEquals(_allCoursesSource, value))
{
_allCoursesSource = value;
RaisePropertyChanged("AllCoursesSource");
}
}
}
private CollectionViewSource _allCoursesSource;
/// <summary>
/// CurrentCourse returns/updates CurrentCourse from _schoolModel,
/// _currentCourseCache keeps a local reference to the object and it
/// syncs with _schoolModel.CurrentCourse when navigates to this page
/// </summary>
public Course CurrentCourse
{
get
{
return _schoolModel != null ? _schoolModel.CurrentCourse : null;
}
private set
{
if (!ReferenceEquals(_currentCourseCache, value))
{
_currentCourseCache = value;
if (_schoolModel != null) _schoolModel.CurrentCourse = _currentCourseCache;
RaisePropertyChanged("CurrentCourse");
}
}
}
private Course _currentCourseCache;
public CollectionViewSource EnrollmentsSource
{
get { return _enrollmentsSource; }
private set
{
if (!ReferenceEquals(_enrollmentsSource, value))
{
_enrollmentsSource = value;
RaisePropertyChanged("EnrollmentsSource");
}
}
}
private CollectionViewSource _enrollmentsSource;
public Enrollment CurrentEnrollment
{
get { return _currentEnrollment; }
private set
{
if (!ReferenceEquals(_currentEnrollment, value))
{
_currentEnrollment = value;
RaisePropertyChanged("CurrentEnrollment");
}
}
}
private Enrollment _currentEnrollment;
private ObservableCollection<Student> _allStudents;
public CollectionViewSource AllStudentsSource
{
get { return _allStudentsSource; }
private set
{
if (!ReferenceEquals(_allStudentsSource, value))
{
_allStudentsSource = value;
RaisePropertyChanged("AllStudentsSource");
}
}
}
private CollectionViewSource _allStudentsSource;
private ObservableCollection<Instructor> _allInstructors;
public CollectionViewSource AllInstructorsSource
{
get { return _allInstructorsSource; }
private set
{
if (!ReferenceEquals(_allInstructorsSource, value))
{
_allInstructorsSource = value;
RaisePropertyChanged("AllInstructorsSource");
}
}
}
private CollectionViewSource _allInstructorsSource;
public bool CourseFormInEdit
{
get { return _courseFormInEdit; }
private set
{
if (_courseFormInEdit != value)
{
_courseFormInEdit = value;
RaisePropertyChanged("CourseFormInEdit");
}
}
}
private bool _courseFormInEdit;
public bool CurrentCourseHasErrors
{
get { return _currentCourseHasErrors; }
set
{
if (_currentCourseHasErrors != value)
{
_currentCourseHasErrors = value;
RaisePropertyChanged("CurrentCourseHasErrors");
}
}
}
private bool _currentCourseHasErrors;
public bool EnrollmentFormInEdit
{
get { return _enrollmentFormInEdit; }
private set
{
if (_enrollmentFormInEdit != value)
{
_enrollmentFormInEdit = value;
RaisePropertyChanged("EnrollmentFormInEdit");
}
}
}
private bool _enrollmentFormInEdit;
public bool CurrentEnrollmentHasErrors
{
get { return _currentEnrollmentHasErrors; }
set
{
if (_currentEnrollmentHasErrors != value)
{
_currentEnrollmentHasErrors = value;
RaisePropertyChanged("CurrentEnrollmentHasErrors");
}
}
}
private bool _currentEnrollmentHasErrors;
public bool CourseListIsEnabled
{
get { return _courseListIsEnabled; }
private set
{
if (_courseListIsEnabled != value)
{
_courseListIsEnabled = value;
RaisePropertyChanged("CourseListIsEnabled");
}
}
}
private bool _courseListIsEnabled = true;
public bool EnrollmentListIsEnabled
{
get { return _enrollmentListIsEnabled; }
private set
{
if (_enrollmentListIsEnabled != value)
{
_enrollmentListIsEnabled = value;
RaisePropertyChanged("EnrollmentListIsEnabled");
}
}
}
private bool _enrollmentListIsEnabled = true;
public bool StudentComboIsEditable
{
get { return _studentComboIsEditable; }
private set
{
if (_studentComboIsEditable != value)
{
_studentComboIsEditable = value;
RaisePropertyChanged("StudentComboIsEditable");
}
}
}
private bool _studentComboIsEditable;
#endregion "Public Properties"
#region "Public Commands"
/// <summary>
/// Command for Page Loaded event
/// </summary>
public RelayCommand PageLoadedCommand
{
get
{
if (_pageLoadedCommand == null)
{
_pageLoadedCommand = new RelayCommand(
OnPageLoadedCommand);
}
return _pageLoadedCommand;
}
}
private RelayCommand _pageLoadedCommand;
private void OnPageLoadedCommand()
{
// synchronize _schoolModel.CoursesList with local cache
if (_schoolModel != null && _allCoursesCache != null)
_schoolModel.CoursesList = _allCoursesCache;
// synchronize _schoolModel.CurrentCourse with local cache
if (_schoolModel != null && _currentCourseCache != null)
_schoolModel.CurrentCourse = _currentCourseCache;
}
/// <summary>
/// Command for Page Unloaded event
/// </summary>
public RelayCommand PageUnLoadedCommand
{
get
{
if (_pageUnLoadedCommand == null)
{
_pageUnLoadedCommand = new RelayCommand(
OnPageUnLoadedCommand);
}
return _pageUnLoadedCommand;
}
}
private RelayCommand _pageUnLoadedCommand;
private void OnPageUnLoadedCommand()
{
// clean up
if (_schoolModel != null)
{
_schoolModel.CoursesList = null;
_schoolModel.CurrentCourse = null;
}
}
/// <summary>
/// Add course command. We can add a new course
/// when neither course nor enrollment form is in edit
/// </summary>
public RelayCommand AddCourseCommand
{
get
{
if (_addCourseCommand == null)
{
_addCourseCommand = new RelayCommand(
OnAddCourseCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit);
}
return _addCourseCommand;
}
}
private RelayCommand _addCourseCommand;
private void OnAddCourseCommand()
{
// create a temporary courseId
int newCourseId = AllCourses.Count > 0
? ((from course in AllCourses select Math.Abs(course.CourseId)).Max() + 1)*(-1)
: -1;
// create a new course
CurrentCourse = new Course
{
SuspendValidation = true,
CourseId = newCourseId,
Title = string.Empty
};
CurrentCourse.SuspendValidation = false;
// no current enrollment yet
EnrollmentsSource = new CollectionViewSource {Source = CurrentCourse.Enrollments};
EnrollmentsSource.SortDescriptions.Add(new SortDescription("EnrollmentId", ListSortDirection.Ascending));
EnrollmentsSource.View.CurrentChanged += EnrollmentsSourceView_CurrentChanged;
CurrentEnrollment = null;
// and begin edit
OnEditCommitCourseCommand();
}
/// <summary>
/// Delete course command. We can delete an course
/// when the current course is not null, and neither course
/// nor enrollment form is in edit
/// </summary>
public RelayCommand DeleteCourseCommand
{
get
{
if (_deleteCourseCommand == null)
{
_deleteCourseCommand = new RelayCommand(
OnDeleteCourseCommand,
() => (CurrentCourse != null) && !CourseFormInEdit && !EnrollmentFormInEdit);
}
return _deleteCourseCommand;
}
}
private RelayCommand _deleteCourseCommand;
private void OnDeleteCourseCommand()
{
try
{
if (CurrentCourse != null)
{
// ask to confirm deleting the current course
DialogMessage dialogMessage = new DialogMessage(
this,
ApplicationStrings.DeleteCurrentCourseMessageBoxText,
s =>
{
if (s == MessageBoxResult.OK)
{
if (CurrentCourse.ChangeTracker.State == ObjectState.Added)
{
// if State is Added, simply remove from the CoursesList
// as the database does not have this record yet
CurrentCourse.MarkAsDeleted();
AllCourses.Remove(CurrentCourse);
}
else
{
// if confirmed, remove current course
CurrentCourse.MarkAsDeleted();
_schoolModel.SaveCourseChangesAsync(false);
}
}
})
{
Button = MessageBoxButton.OKCancel,
Caption = ApplicationStrings.ConfirmMessageBoxCaption
};
AppMessages.PleaseConfirmMessage.Send(dialogMessage);
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
/// <summary>
/// Edit/Commit an course. We can edit/commit an course
/// when current course is not null
/// </summary>
public RelayCommand EditCommitCourseCommand
{
get
{
if (_editCommitCourseCommand == null)
{
_editCommitCourseCommand = new RelayCommand(
OnEditCommitCourseCommand,
() => (CurrentCourse != null));
}
return _editCommitCourseCommand;
}
}
private RelayCommand _editCommitCourseCommand;
private void OnEditCommitCourseCommand()
{
if (CurrentCourse != null)
{
if (CourseFormInEdit)
{
// if passed validation, end editing
if (!CurrentCourseHasErrors && CurrentCourse.TryValidate())
{
CourseFormEndEdit();
// if this is a new course, add to the CoursesList
if (CurrentCourse.ChangeTracker.State == ObjectState.Added)
{
var alreadyAdded = AllCourses.Any(n => n.CourseId == CurrentCourse.CourseId);
if (!alreadyAdded)
{
AllCourses.Add(CurrentCourse);
AllCoursesSource.View.MoveCurrentTo(CurrentCourse);
}
}
}
}
else
{
CourseFormBeginEdit();
}
}
}
/// <summary>
/// Cancel edit an course. We can cancel edit an course
/// when current course is not null, and the course form
/// is currently in edit
/// </summary>
public RelayCommand CancelEditCourseCommand
{
get
{
if (_cancelEditCourseCommand == null)
{
_cancelEditCourseCommand = new RelayCommand(
OnCancelEditCourseCommand,
() => (CurrentCourse != null) && CourseFormInEdit);
}
return _cancelEditCourseCommand;
}
}
private RelayCommand _cancelEditCourseCommand;
private void OnCancelEditCourseCommand()
{
if (CurrentCourse != null)
{
CourseFormCancelEdit();
// if this is a new course, simply discard that record
if (CurrentCourse.ChangeTracker.State == ObjectState.Added)
{
var alreadyAdded = AllCourses.Any(n => n.CourseId == CurrentCourse.CourseId);
if (!alreadyAdded)
{
if (EnrollmentFormInEdit) EnrollmentFormEndEdit();
AllCoursesSourceView_CurrentChanged(this, null);
}
}
}
}
/// <summary>
/// Add enrollment command. We can add a new enrollment
/// when current course is not null, there are some
/// students to be selected from and the enrollment form
/// is not in edit
/// </summary>
public RelayCommand AddEnrollmentCommand
{
get
{
if (_addEnrollmentCommand == null)
{
_addEnrollmentCommand = new RelayCommand(
OnAddEnrollmentCommand,
() => (CurrentCourse != null) && (_allStudents != null)
&& (_allStudents.Count > 0) && !EnrollmentFormInEdit);
}
return _addEnrollmentCommand;
}
}
private RelayCommand _addEnrollmentCommand;
private void OnAddEnrollmentCommand()
{
if (CurrentCourse != null)
{
// create a new enrollment
CurrentEnrollment = new Enrollment
{
SuspendValidation = true,
Course = null,
Paid = false
};
CurrentEnrollment.SuspendValidation = false;
// and begin edit
OnEditCommitEnrollmentCommand();
}
}
/// <summary>
/// Delete enrollment command. We can delete an enrollment
/// when current enrollment is not null, and the
/// enrollment form is not in edit
/// </summary>
public RelayCommand DeleteEnrollmentCommand
{
get
{
if (_deleteEnrollmentCommand == null)
{
_deleteEnrollmentCommand = new RelayCommand(
OnDeleteEnrollmentCommand,
() => (CurrentEnrollment != null) && !EnrollmentFormInEdit);
}
return _deleteEnrollmentCommand;
}
}
private RelayCommand _deleteEnrollmentCommand;
private void OnDeleteEnrollmentCommand()
{
if (CurrentEnrollment != null)
{
CurrentEnrollment.MarkAsDeleted();
}
}
/// <summary>
/// Edit/Commit an course. We can edit/commit an enrollment
/// when current enrollment is not null
/// </summary>
public RelayCommand EditCommitEnrollmentCommand
{
get
{
if (_editCommitEnrollmentCommand == null)
{
_editCommitEnrollmentCommand = new RelayCommand(
OnEditCommitEnrollmentCommand,
() => (CurrentEnrollment != null));
}
return _editCommitEnrollmentCommand;
}
}
private RelayCommand _editCommitEnrollmentCommand;
private void OnEditCommitEnrollmentCommand()
{
if (CurrentEnrollment != null)
{
if (EnrollmentFormInEdit)
{
// if passed validation, end editing
if (!CurrentEnrollmentHasErrors && CurrentEnrollment.TryValidate())
{
EnrollmentFormEndEdit();
// if this is a new enrollment, add to CurrentCourse.Enrollments
if (CurrentEnrollment.ChangeTracker.State == ObjectState.Added)
{
var alreadyAdded = CurrentEnrollment.Course != null;
if (!alreadyAdded)
{
// add to the CurrentCourse
CurrentEnrollment.Course = CurrentCourse;
// add navigation property Student
var student = _allStudents
.First(n => n.PersonId == CurrentEnrollment.StudentId);
var currentStudent = new Student
{
PersonId = student.PersonId,
Name = student.Name,
EnrollmentDate = student.EnrollmentDate,
Version = student.Version
};
CurrentEnrollment.Student = currentStudent;
currentStudent.MarkAsUnchanged();
EnrollmentsSource.View.MoveCurrentTo(CurrentEnrollment);
}
}
}
}
else
{
EnrollmentFormBeginEdit();
}
}
}
/// <summary>
/// Cancel edit an enrollment. We can cancel edit an enrollment
/// when current enrollment is not null, and the
/// enrollment form is currently in edit
/// </summary>
public RelayCommand CancelEditEnrollmentCommand
{
get
{
if (_cancelEditEnrollmentCommand == null)
{
_cancelEditEnrollmentCommand = new RelayCommand(
OnCancelEditEnrollmentCommand,
() => (CurrentEnrollment != null) && EnrollmentFormInEdit);
}
return _cancelEditEnrollmentCommand;
}
}
private RelayCommand _cancelEditEnrollmentCommand;
private void OnCancelEditEnrollmentCommand()
{
if (CurrentEnrollment != null)
{
EnrollmentFormCancelEdit();
// if this is a new enrollment, simply discard that record
if (CurrentEnrollment.ChangeTracker.State == ObjectState.Added)
{
var alreadyAdded = CurrentEnrollment.Course != null;
if (!alreadyAdded)
{
EnrollmentsSourceView_CurrentChanged(this, null);
}
}
}
}
/// <summary>
/// Refresh current course command. We can refresh
/// current course when neither course nor enrollment
/// form is in edit, and there is no change to save for
/// the current course
/// </summary>
public RelayCommand RefreshCourseCommand
{
get
{
if (_refreshCourseCommand == null)
{
_refreshCourseCommand = new RelayCommand(
OnRefreshCourseCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && !(_schoolModel.CurrentCourseHasChanges));
}
return _refreshCourseCommand;
}
}
private RelayCommand _refreshCourseCommand;
private void OnRefreshCourseCommand()
{
if (CurrentCourse != null)
{
_schoolModel.GetCourseByIdAsync(CurrentCourse.CourseId);
}
}
/// <summary>
/// Submit change command. We can submit changes
/// when neither course nor enrollment form is in edit,
/// and there are changes to save for current course
/// </summary>
public RelayCommand SubmitCourseChangeCommand
{
get
{
if (_submitCourseChangeCommand == null)
{
_submitCourseChangeCommand = new RelayCommand(
OnSubmitCourseChangeCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && (_schoolModel.CurrentCourseHasChanges));
}
return _submitCourseChangeCommand;
}
}
private RelayCommand _submitCourseChangeCommand;
private void OnSubmitCourseChangeCommand()
{
try
{
if (!_schoolModel.IsBusy && CurrentCourse != null)
{
// we only save changes when current course and its enrollments passed validation
var passedValidation = CurrentCourse.TryValidateObjectGraph();
if (!passedValidation) return;
// save changes for CurrentCourse only
_schoolModel.SaveCourseChangesAsync(false);
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
/// <summary>
/// Cancel change command. We can cancel changes
/// when neither course nor enrollment form is in edit,
/// and there are changes to cancel for current course
/// </summary>
public RelayCommand CancelCourseChangeCommand
{
get
{
if (_cancelCourseChangeCommand == null)
{
_cancelCourseChangeCommand = new RelayCommand(
OnCancelCourseChangeCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && (_schoolModel.CurrentCourseHasChanges));
}
return _cancelCourseChangeCommand;
}
}
private RelayCommand _cancelCourseChangeCommand;
private void OnCancelCourseChangeCommand()
{
try
{
if (!_schoolModel.IsBusy && CurrentCourse != null)
{
// ask to confirm canceling changes
DialogMessage dialogMessage = new DialogMessage(
this,
ApplicationStrings.CancelAnyChangesMessageBoxText,
s =>
{
if (s == MessageBoxResult.OK)
{
// if confirmed, cancel changes for CurrentCourse
_schoolModel.RejectCourseChanges(false);
}
})
{
Button = MessageBoxButton.OKCancel,
Caption = ApplicationStrings.ConfirmMessageBoxCaption
};
AppMessages.PleaseConfirmMessage.Send(dialogMessage);
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
/// <summary>
/// Refresh course list command. We can refresh course list
/// when neither course nor enrollment form is in edit,
/// and there is no change to save
/// </summary>
public RelayCommand RefreshAllCommand
{
get
{
if (_refreshAllCommand == null)
{
_refreshAllCommand = new RelayCommand(
OnRefreshAllCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && !(_schoolModel.CoursesListHasChanges));
}
return _refreshAllCommand;
}
}
private RelayCommand _refreshAllCommand;
private void OnRefreshAllCommand()
{
// get students
_schoolModel.GetStudentsAsync("None", "CoursePage");
// get instructors
_schoolModel.GetInstructorsAsync("None", "CoursePage");
// get courses
_schoolModel.GetCoursesAsync("CoursePage");
}
/// <summary>
/// Submit change command. We can submit changes
/// when neither course nor enrollment form is in edit,
/// and there are changes to save
/// </summary>
public RelayCommand SubmitAllChangeCommand
{
get
{
if (_submitAllChangeCommand == null)
{
_submitAllChangeCommand = new RelayCommand(
OnSubmitAllChangeCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && (_schoolModel.CoursesListHasChanges));
}
return _submitAllChangeCommand;
}
}
private RelayCommand _submitAllChangeCommand;
private void OnSubmitAllChangeCommand()
{
try
{
if (!_schoolModel.IsBusy)
{
if (AllCourses != null)
{
// we only save changes when all courses and their enrollments passed validation
var passedValidation = AllCourses.All(o => o.TryValidateObjectGraph());
if (!passedValidation) return;
// save changes for CoursesList
_schoolModel.SaveCourseChangesAsync();
}
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
/// <summary>
/// Cancel change command. We can cancel changes
/// when neither course nor enrollment form is in edit,
/// and there are changes to cancel
/// </summary>
public RelayCommand CancelAllChangeCommand
{
get
{
if (_cancelAllChangeCommand == null)
{
_cancelAllChangeCommand = new RelayCommand(
OnCancelAllChangeCommand,
() => !CourseFormInEdit && !EnrollmentFormInEdit &&
(_schoolModel != null) && (_schoolModel.CoursesListHasChanges));
}
return _cancelAllChangeCommand;
}
}
private RelayCommand _cancelAllChangeCommand;
private void OnCancelAllChangeCommand()
{
try
{
if (!_schoolModel.IsBusy)
{
// ask to confirm canceling changes
DialogMessage dialogMessage = new DialogMessage(
this,
ApplicationStrings.CancelAnyChangesMessageBoxText,
s =>
{
if (s == MessageBoxResult.OK)
{
// if confirmed, cancel changes for CoursesList
_schoolModel.RejectCourseChanges();
}
})
{
Button = MessageBoxButton.OKCancel,
Caption = ApplicationStrings.ConfirmMessageBoxCaption
};
AppMessages.PleaseConfirmMessage.Send(dialogMessage);
}
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
#endregion "Public Commands"
#region "Private Methods"
/// <summary>
/// CourseListIsEnabled is set to true only when
/// course is not in edit and enrollment is also not
/// in edit
/// </summary>
private void UpdateCourseListIsEnabled()
{
CourseListIsEnabled = !CourseFormInEdit && !EnrollmentFormInEdit;
}
/// <summary>
/// EnrollmentListIsEnabled is set to true only when
/// enrollment is not in edit
/// </summary>
private void UpdateEnrollmentListIsEnabled()
{
EnrollmentListIsEnabled = !EnrollmentFormInEdit;
}
/// <summary>
/// StudentComboIsEditable is set to true only when
/// enrollment is in edit and a new enrollment has just get
/// created
/// </summary>
private void UpdateStudentComboIsEditable()
{
StudentComboIsEditable = EnrollmentFormInEdit && CurrentEnrollment != null &&
CurrentEnrollment.ChangeTracker.State == ObjectState.Added &&
CurrentEnrollment.Course == null;
}
private void CourseFormBeginEdit()
{
if (CurrentCourse != null)
{
CurrentCourse.BeginEdit();
AppMessages.BeginEditMessage.Send("Course");
CourseFormInEdit = true;
}
}
private void CourseFormEndEdit()
{
AppMessages.EndEditMessage.Send("Course");
CourseFormInEdit = false;
if (CurrentCourse != null) CurrentCourse.EndEdit();
}
private void CourseFormCancelEdit()
{
if (CurrentCourse != null)
{
AppMessages.CancelEditMessage.Send("Course");
CourseFormInEdit = false;
CurrentCourse.CancelEdit();
}
}
private void EnrollmentFormBeginEdit()
{
if (CurrentEnrollment != null)
{
CurrentEnrollment.BeginEdit();
AppMessages.BeginEditMessage.Send("Enrollment");
EnrollmentFormInEdit = true;
}
}
private void EnrollmentFormEndEdit()
{
AppMessages.EndEditMessage.Send("Enrollment");
EnrollmentFormInEdit = false;
if (CurrentEnrollment != null) CurrentEnrollment.EndEdit();
}
private void EnrollmentFormCancelEdit()
{
if (CurrentEnrollment != null)
{
AppMessages.CancelEditMessage.Send("Enrollment");
EnrollmentFormInEdit = false;
CurrentEnrollment.CancelEdit();
}
}
/// <summary>
/// Event handler for GetStudentsCompleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_GetStudentsCompleted(object sender, ResultsArgs<Student> e)
{
var screenName = e.UserState as string;
if (!string.Equals(screenName, "CoursePage")) return;
if (!e.HasError)
{
// clear any previous error after a successful call
_schoolModel.ClearLastError();
// sort by student name
_allStudents = new ObservableCollection<Student>(e.Results.OrderBy(n => n.Name));
AllStudentsSource = new CollectionViewSource {Source = _allStudents};
AllStudentsSource.Filter += AllStudentsSource_Filter;
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
/// <summary>
/// Event handler for Filter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AllStudentsSource_Filter(object sender, FilterEventArgs e)
{
Student item = e.Item as Student;
if (item != null && CurrentCourse != null)
{
e.Accepted = !CurrentCourse.Enrollments.Any(n => n.StudentId == item.PersonId) ||
((CurrentEnrollment == null) || (CurrentEnrollment.StudentId == item.PersonId));
}
}
/// <summary>
/// Event handler for GetInstructorsCompleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_GetInstructorsCompleted(object sender, ResultsArgs<Instructor> e)
{
var screenName = e.UserState as string;
if (!string.Equals(screenName, "CoursePage")) return;
if (!e.HasError)
{
// clear any previous error after a successful call
_schoolModel.ClearLastError();
// sort by instructor name
_allInstructors = new ObservableCollection<Instructor>(e.Results.OrderBy(n => n.Name));
AllInstructorsSource = new CollectionViewSource {Source = _allInstructors};
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
/// <summary>
/// Event handler for GetCoursesCompleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_GetCoursesCompleted(object sender, ResultsArgs<Course> e)
{
var screenName = e.UserState as string;
if (!string.Equals(screenName, "CoursePage")) return;
if (!e.HasError)
{
// clear any previous error after a successful call
_schoolModel.ClearLastError();
// cancel any changes before setting AllCoursesSource
if (_schoolModel.CoursesListHasChanges)
{
_schoolModel.RejectCourseChanges();
}
AllCourses = new ObservableCollection<Course>(e.Results);
AllCoursesSource = new CollectionViewSource {Source = AllCourses};
// sort by CourseId
AllCoursesSource.SortDescriptions.Add(new SortDescription("CourseId", ListSortDirection.Ascending));
AllCoursesSource.View.CurrentChanged += AllCoursesSourceView_CurrentChanged;
if (AllCourses.Count >= 1)
{
if (CurrentCourse != null)
{
var currentCourse = AllCourses
.FirstOrDefault(n => n.CourseId == CurrentCourse.CourseId);
if (currentCourse != null)
AllCoursesSource.View.MoveCurrentTo(currentCourse);
else
// set the first row as the current course in edit
AllCoursesSource.View.MoveCurrentToFirst();
}
else
{
// set the first row as the current course in edit
AllCoursesSource.View.MoveCurrentToFirst();
}
// assign the current item to CurrentCourse
CurrentCourse = (Course) AllCoursesSource.View.CurrentItem;
// set EnrollmentsSource
if (CurrentCourse != null)
{
EnrollmentsSource = new CollectionViewSource {Source = CurrentCourse.Enrollments};
// sort by EnrollmentId
EnrollmentsSource.SortDescriptions.Add(new SortDescription("EnrollmentId", ListSortDirection.Ascending));
EnrollmentsSource.View.CurrentChanged += EnrollmentsSourceView_CurrentChanged;
// set the first row as the current enrollment in edit
if (CurrentCourse.Enrollments != null && CurrentCourse.Enrollments.Count >= 1)
{
EnrollmentsSource.View.MoveCurrentToFirst();
CurrentEnrollment = (Enrollment) EnrollmentsSource.View.CurrentItem;
}
else
{
CurrentEnrollment = null;
}
}
}
else
{
CurrentCourse = null;
EnrollmentsSource = new CollectionViewSource();
CurrentEnrollment = null;
}
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
/// <summary>
/// Event handler for CurrentChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AllCoursesSourceView_CurrentChanged(object sender, EventArgs e)
{
CurrentCourse = (Course) AllCoursesSource.View.CurrentItem;
// set EnrollmentsSource
if (CurrentCourse != null)
{
EnrollmentsSource = new CollectionViewSource {Source = CurrentCourse.Enrollments};
// sort by EnrollmentId
EnrollmentsSource.SortDescriptions.Add(new SortDescription("EnrollmentId", ListSortDirection.Ascending));
EnrollmentsSource.View.CurrentChanged += EnrollmentsSourceView_CurrentChanged;
// set the current enrollment in edit
if (CurrentCourse.Enrollments != null && CurrentCourse.Enrollments.Count >= 1)
{
CurrentEnrollment = (Enrollment) EnrollmentsSource.View.CurrentItem;
}
else
{
CurrentEnrollment = null;
}
}
else
{
EnrollmentsSource = new CollectionViewSource();
CurrentEnrollment = null;
}
}
/// <summary>
/// Event handler for CurrentChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EnrollmentsSourceView_CurrentChanged(object sender, EventArgs e)
{
CurrentEnrollment = (Enrollment) EnrollmentsSource.View.CurrentItem;
}
/// <summary>
/// Event handler for GetCourseByIdCompleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_GetCourseByIdCompleted(object sender, ResultArgs<Course> e)
{
if (!e.HasError)
{
// clear any previous error after a successful call
_schoolModel.ClearLastError();
Course currentCourse = e.Results;
if (currentCourse != null)
{
// find the matching current course from AllCourses list
Course matchedCourse = AllCourses.Single(n => n.CourseId == currentCourse.CourseId);
// replace matchedCourse from AllCourses list with what is returned from GetCourseById
int index = AllCourses.IndexOf(matchedCourse);
AllCourses.Remove(matchedCourse);
AllCourses.Insert(index, currentCourse);
AllCoursesSource.View.MoveCurrentTo(currentCourse);
}
else
{
DialogMessage dialogMessage = new DialogMessage(
this,
ErrorResources.CurrentCourseDoesNotExistMessageBoxText,
null)
{
Button = MessageBoxButton.OK,
Caption = ApplicationStrings.WarningMessageBoxCaption
};
AppMessages.StatusUpdateMessage.Send(dialogMessage);
}
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
/// <summary>
/// Event handler for SaveCourseChangesCompleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_SaveCourseChangesCompleted(object sender, ResultArgs<string> e)
{
if (!e.HasError)
{
// clear any previous error after a successful call
_schoolModel.ClearLastError();
// check whether there is any warning message returned
if (!string.IsNullOrEmpty(e.Results))
{
DialogMessage dialogMessage = new DialogMessage(
this,
e.Results,
null)
{
Button = MessageBoxButton.OK,
Caption = ApplicationStrings.WarningMessageBoxCaption
};
AppMessages.StatusUpdateMessage.Send(dialogMessage);
// If last operation is a delete operation, call reject changes
if (CurrentCourse != null && CurrentCourse.ChangeTracker.State == ObjectState.Deleted)
{
_schoolModel.RejectCourseChanges(false);
}
}
else
{
if (_schoolModel.CoursesListHasChanges)
{
if (!_schoolModel.CurrentCourseHasChanges)
// only refresh current course after Insert/Update/Delete
OnRefreshCourseCommand();
}
else
// refresh the CoursesList after Insert/Update/Delete
OnRefreshAllCommand();
}
}
else
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(e.Error);
}
}
/// <summary>
/// Event handler for PropertyChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _schoolModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "CoursesListHasChanges":
RefreshAllCommand.RaiseCanExecuteChanged();
SubmitAllChangeCommand.RaiseCanExecuteChanged();
CancelAllChangeCommand.RaiseCanExecuteChanged();
break;
case "CurrentCourseHasChanges":
RefreshCourseCommand.RaiseCanExecuteChanged();
SubmitCourseChangeCommand.RaiseCanExecuteChanged();
CancelCourseChangeCommand.RaiseCanExecuteChanged();
break;
}
}
/// <summary>
/// Event handler for PropertyChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CoursePageViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "CurrentCourse":
AddEnrollmentCommand.RaiseCanExecuteChanged();
DeleteCourseCommand.RaiseCanExecuteChanged();
EditCommitCourseCommand.RaiseCanExecuteChanged();
CancelEditCourseCommand.RaiseCanExecuteChanged();
break;
case "CurrentEnrollment":
DeleteEnrollmentCommand.RaiseCanExecuteChanged();
EditCommitEnrollmentCommand.RaiseCanExecuteChanged();
CancelEditEnrollmentCommand.RaiseCanExecuteChanged();
UpdateStudentComboIsEditable();
if (AllStudentsSource != null && AllStudentsSource.View != null)
AllStudentsSource.View.Refresh();
break;
case "AllStudentsSource":
AddEnrollmentCommand.RaiseCanExecuteChanged();
break;
case "CourseFormInEdit":
AddCourseCommand.RaiseCanExecuteChanged();
DeleteCourseCommand.RaiseCanExecuteChanged();
CancelEditCourseCommand.RaiseCanExecuteChanged();
RefreshCourseCommand.RaiseCanExecuteChanged();
SubmitCourseChangeCommand.RaiseCanExecuteChanged();
CancelCourseChangeCommand.RaiseCanExecuteChanged();
RefreshAllCommand.RaiseCanExecuteChanged();
SubmitAllChangeCommand.RaiseCanExecuteChanged();
CancelAllChangeCommand.RaiseCanExecuteChanged();
UpdateCourseListIsEnabled();
break;
case "EnrollmentFormInEdit":
AddCourseCommand.RaiseCanExecuteChanged();
DeleteCourseCommand.RaiseCanExecuteChanged();
AddEnrollmentCommand.RaiseCanExecuteChanged();
DeleteEnrollmentCommand.RaiseCanExecuteChanged();
CancelEditEnrollmentCommand.RaiseCanExecuteChanged();
RefreshCourseCommand.RaiseCanExecuteChanged();
SubmitCourseChangeCommand.RaiseCanExecuteChanged();
CancelCourseChangeCommand.RaiseCanExecuteChanged();
RefreshAllCommand.RaiseCanExecuteChanged();
SubmitAllChangeCommand.RaiseCanExecuteChanged();
CancelAllChangeCommand.RaiseCanExecuteChanged();
UpdateCourseListIsEnabled();
UpdateEnrollmentListIsEnabled();
UpdateStudentComboIsEditable();
break;
}
}
#endregion "Private Methods"
}
}