Click here to Skip to main content
15,885,767 members
Articles / Desktop Programming / WPF

Building WPF Applications with Self-Tracking Entity Generator and Visual Studio 2012 - Project Setup

Rate me:
Please Sign up or sign in to vote.
5.00/5 (14 votes)
17 Mar 2013CPOL8 min read 68.5K   3.5K   44  
This article describes the project setup of building a WPF sample application with Self-Tracking Entity Generator and Visual Studio 2012.
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
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 readonly ISchoolModel _schoolModel;
        private const int PageSize = 5;
        private string _filter = string.Empty;

        #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;

            // set current page
            CurrentPage = 1;

            // get students
            var studentQuery = ClientQuerySet.Students.AsClientQuery();
            _schoolModel.GetStudentsAsync(studentQuery, "CoursePage");
            // get instructors
            var instructorQuery = ClientQuerySet.Instructors.AsClientQuery();
            _schoolModel.GetInstructorsAsync(instructorQuery, "CoursePage");
            // get courses
            var courseQuery = ClientQuerySet.Courses
                .Include("Enrollments.Student")
                .OrderBy(n => n.CourseId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetCoursesAsync(courseQuery, "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;

        public int CurrentPage
        {
            get { return _currentPage; }
            private set
            {
                if (_currentPage != value)
                {
                    _currentPage = value;
                    RaisePropertyChanged("CurrentPage");
                }
            }
        }

        private int _currentPage;

        public bool CanMovePrevPage
        {
            get { return _canMovePrevPage; }
            private set
            {
                if (_canMovePrevPage != value)
                {
                    _canMovePrevPage = value;
                    RaisePropertyChanged("CanMovePrevPage");
                }
            }
        }

        private bool _canMovePrevPage;

        public bool CanMoveNextPage
        {
            get { return _canMoveNextPage; }
            private set
            {
                if (_canMoveNextPage != value)
                {
                    _canMoveNextPage = value;
                    RaisePropertyChanged("CanMoveNextPage");
                }
            }
        }

        private bool _canMoveNextPage;

        #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;

            // if CurrentCourseHasErrors or CurrentEnrollmentHasErrors,
            // call TryValidate() to push the new error messages into the ValidationSummary
            if (CurrentCourseHasErrors && CurrentCourse != null) CurrentCourse.TryValidate();
            if (CurrentEnrollmentHasErrors && CurrentEnrollment != null) CurrentEnrollment.TryValidate();
        }

        /// <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>
        /// Previous Page Command
        /// </summary>
        public RelayCommand PrevPageCommand
        {
            get
            {
                if (_prevPageCommand == null)
                {
                    _prevPageCommand = new RelayCommand(
                        OnPrevPageCommand,
                        () => CanMovePrevPage &&
                              !CourseFormInEdit && !EnrollmentFormInEdit &&
                              (_schoolModel != null) && !(_schoolModel.CoursesListHasChanges));
                }
                return _prevPageCommand;
            }
        }

        private RelayCommand _prevPageCommand;

        private void OnPrevPageCommand()
        {
            if (CurrentPage > 1)
            {
                CurrentPage--;
                // get courses
                var query = ClientQuerySet.Courses.Include("Enrollments.Student");
                // apply filter if necessary
                if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Title.Contains(_filter));
                var courseQuery = query.OrderBy(n => n.CourseId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetCoursesAsync(courseQuery, "CoursePage");
            }
        }

        /// <summary>
        /// Next Page Command
        /// </summary>
        public RelayCommand NextPageCommand
        {
            get
            {
                if (_nextPageCommand == null)
                {
                    _nextPageCommand = new RelayCommand(
                        OnNextPageCommand,
                        () => CanMoveNextPage &&
                              !CourseFormInEdit && !EnrollmentFormInEdit &&
                              (_schoolModel != null) && !(_schoolModel.CoursesListHasChanges));
                }
                return _nextPageCommand;
            }
        }

        private RelayCommand _nextPageCommand;

        private void OnNextPageCommand()
        {
            CurrentPage++;
            // get courses
            var query = ClientQuerySet.Courses.Include("Enrollments.Student");
            // apply filter if necessary
            if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Title.Contains(_filter));
            var courseQuery = query.OrderBy(n => n.CourseId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetCoursesAsync(courseQuery, "CoursePage");
        }

        /// <summary>
        /// Filter Title Command
        /// </summary>
        public RelayCommand FilterTitleCommand
        {
            get
            {
                if (_filterTitleCommand == null)
                {
                    _filterTitleCommand = new RelayCommand(
                        OnFilterTitleCommand,
                        () => !CourseFormInEdit && !EnrollmentFormInEdit &&
                              (_schoolModel != null) && !(_schoolModel.CoursesListHasChanges));
                }
                return _filterTitleCommand;
            }
        }

        private RelayCommand _filterTitleCommand;

        private void OnFilterTitleCommand()
        {
            try
            {
                var message = new NotificationMessageAction<string>(this,
                                                                    ApplicationStrings.FilterOnTitleText,
                                                                    OnFilterTitleCallback);

                AppMessages.FilterTextMessage.Send(message);
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private void OnFilterTitleCallback(string s)
        {
            _filter = s;
            CurrentPage = 1;
            // get courses
            var query = ClientQuerySet.Courses.Include("Enrollments.Student");
            // apply filter if necessary
            if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Title.Contains(_filter));
            var courseQuery = query.OrderBy(n => n.CourseId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetCoursesAsync(courseQuery, "CoursePage");
        }

        /// <summary>
        /// Filter Reset Command
        /// </summary>
        public RelayCommand FilterResetCommand
        {
            get
            {
                if (_filterResetCommand == null)
                {
                    _filterResetCommand = new RelayCommand(
                        OnFilterResetCommand,
                        () => !CourseFormInEdit && !EnrollmentFormInEdit &&
                              (_schoolModel != null) && !(_schoolModel.CoursesListHasChanges));
                }
                return _filterResetCommand;
            }
        }

        private RelayCommand _filterResetCommand;

        private void OnFilterResetCommand()
        {
            if (!string.IsNullOrWhiteSpace(_filter))
            {
                _filter = string.Empty;
                CurrentPage = 1;
                // get courses
                var courseQuery = ClientQuerySet.Courses
                    .Include("Enrollments.Student")
                    .OrderBy(n => n.CourseId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetCoursesAsync(courseQuery, "CoursePage");
            }
        }

        /// <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;
            // set up event handler for CollectionChanged
            if (CurrentCourse.Enrollments != null)
                CurrentCourse.Enrollments.CollectionChanged += Enrollments_CollectionChanged;
            // 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
                    var dialogMessage = new DialogMessage(this,
                                                          ApplicationStrings.DeleteCurrentCourseMessageBoxText,
                                                          OnDeleteCourseCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = ApplicationStrings.ConfirmMessageBoxCaption
                                            };

                    AppMessages.PleaseConfirmMessage.Send(dialogMessage);
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private void OnDeleteCourseCallback(MessageBoxResult 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);
                }
            }
        }

        /// <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
                    var dialogMessage = new DialogMessage(this,
                                                          ApplicationStrings.CancelAnyChangesMessageBoxText,
                                                          OnCancelCourseCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = ApplicationStrings.ConfirmMessageBoxCaption
                                            };

                    AppMessages.PleaseConfirmMessage.Send(dialogMessage);
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private void OnCancelCourseCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                // if confirmed, cancel changes for CurrentCourse
                _schoolModel.RejectCourseChanges(false);
            }
        }

        /// <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()
        {
            if (!_schoolModel.IsBusy)
            {
                // get students
                var studentQuery = ClientQuerySet.Students.AsClientQuery();
                _schoolModel.GetStudentsAsync(studentQuery, "CoursePage");
                // get instructors
                var instructorQuery = ClientQuerySet.Instructors.AsClientQuery();
                _schoolModel.GetInstructorsAsync(instructorQuery, "CoursePage");
                // get courses
                var query = ClientQuerySet.Courses.Include("Enrollments.Student");
                // apply filter if necessary
                if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Title.Contains(_filter));
                var courseQuery = query.OrderBy(n => n.CourseId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetCoursesAsync(courseQuery, "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
                    var dialogMessage = new DialogMessage(this,
                                                          ApplicationStrings.CancelAnyChangesMessageBoxText,
                                                          OnCancelAllChangeCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = ApplicationStrings.ConfirmMessageBoxCaption
                                            };

                    AppMessages.PleaseConfirmMessage.Send(dialogMessage);
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private void OnCancelAllChangeCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                // if confirmed, cancel changes for CoursesList
                _schoolModel.RejectCourseChanges();
            }
        }

        #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)
        {
            var 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;
                // set CanMovePrevPage and CanMoveNextPage
                CanMovePrevPage = (CurrentPage > 1);
                CanMoveNextPage = (AllCourses.Count == PageSize);

                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)
                    {
                        // set up event handler for CollectionChanged
                        if (CurrentCourse.Enrollments != null)
                            CurrentCourse.Enrollments.CollectionChanged += Enrollments_CollectionChanged;
                        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)
            {
                // set up event handler for CollectionChanged
                if (CurrentCourse.Enrollments != null)
                    CurrentCourse.Enrollments.CollectionChanged += Enrollments_CollectionChanged;
                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
                {
                    var 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))
                {
                    var 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;
            }
        }

        /// <summary>
        /// Event handler for CollectionChanged
        /// Whenever the enrollment number changes for a class, re-validate whether
        /// the current course has already reached enrollment limit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Enrollments_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (CurrentCourse != null)
                CurrentCourse.TryValidate();
        }

        #endregion "Private Methods"
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Weidong has been an information system professional since 1990. He has a Master's degree in Computer Science, and is currently a MCSD .NET

Comments and Discussions