Click here to Skip to main content
15,886,611 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.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;
using SchoolSample.EntityModel.Resource;

namespace SchoolSample.ViewModel
{
    [Export(ViewModelTypes.StudentPageViewModel, typeof (ViewModelBase))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class StudentPageViewModel : ViewModelBase
    {
        #region "Private Data Members"

        private readonly ISchoolModel _schoolModel;
        private const int PageSize = 5;
        private ClientFilter<Student> _currentFilter;
        private ClientFilter<Student> _defaultClientFilter;

        private static readonly ClientQuery<Student> StudentClientQuery =
            ClientQuerySet.Students.Include(n => n.Enrollments.Include(m => m.Course));

        #endregion "Private Data Members"

        #region "Constructor"

        [ImportingConstructor]
        public StudentPageViewModel(ISchoolModel schoolModel)
        {
            _schoolModel = schoolModel;

            // register for StudentDefaultFilterMessage
            AppMessages.StudentDefaultFilterMessage.Register(this, OnStudentDefaultFilterMessage);

            // set up event handling
            _schoolModel.PropertyChanged += _schoolModel_PropertyChanged;
            _schoolModel.GetStudentsCompleted += _schoolModel_GetStudentsCompleted;
            _schoolModel.GetStudentByIdCompleted += _schoolModel_GetStudentByIdCompleted;
            _schoolModel.SaveStudentChangesCompleted += _schoolModel_SaveStudentChangesCompleted;
            _schoolModel.GetDefaultFilterByScreenNameCompleted += _schoolModel_GetDefaultFilterByScreenNameCompleted;
            _schoolModel.SaveDefaultFilterCompleted += _schoolModel_SaveDefaultFilterCompleted;

            PropertyChanged += StudentPageViewModel_PropertyChanged;

            // set enum type
            StudentStatusCollection = new EnumCollection<StatusEnum>(false, SchoolModelResource.ResourceManager);

            // set current page
            CurrentPage = 1;

            // set current filter to order by PersonId
            _currentFilter = new ClientFilter<Student>().OrderBy(n => n.PersonId);

            // get students
            var studentQuery = StudentClientQuery
                .ApplyClientFilter(_currentFilter)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");

            // get default filter
            _schoolModel.GetDefaultFilterByScreenNameAsync("StudentPage");

            // set up initial screen status
            StudentFormEndEdit();
        }

        #endregion "Constructor"

        #region "Public Properties"

        /// <summary>
        /// All students collection returns/updates StudentsList from _schoolModel,
        /// _allStudentsCache keeps a local reference to the list and it syncs with
        /// _schoolModel.StudentsList when navigates to this page
        /// </summary>
        private ObservableCollection<Student> AllStudents
        {
            get { return _schoolModel != null ? _schoolModel.StudentsList : null; }
            set
            {
                if (!ReferenceEquals(_allStudentsCache, value))
                {
                    _allStudentsCache = value;
                    // update StudentsList on the model
                    if (_schoolModel != null) _schoolModel.StudentsList = _allStudentsCache;
                }
            }
        }

        private ObservableCollection<Student> _allStudentsCache;

        public CollectionViewSource AllStudentsSource
        {
            get { return _allStudentsSource; }
            private set
            {
                if (!ReferenceEquals(_allStudentsSource, value))
                {
                    _allStudentsSource = value;
                    RaisePropertyChanged("AllStudentsSource");
                }
            }
        }

        private CollectionViewSource _allStudentsSource;

        /// <summary>
        /// CurrentStudent returns/updates CurrentStudent from _schoolModel,
        /// _currentStudentCache keeps a local reference to the object and it
        /// syncs with _schoolModel.CurrentStudent when navigates to this page 
        /// </summary>
        public Student CurrentStudent
        {
            get { return _schoolModel != null ? _schoolModel.CurrentStudent : null; }
            private set
            {
                if (!ReferenceEquals(_currentStudentCache, value))
                {
                    _currentStudentCache = value;
                    if (_schoolModel != null) _schoolModel.CurrentStudent = _currentStudentCache;
                    RaisePropertyChanged("CurrentStudent");
                }
            }
        }

        private Student _currentStudentCache;

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

        private bool _studentFormInEdit;

        public bool CurrentStudentHasErrors
        {
            get { return _currentStudentHasErrors; }
            set
            {
                if (_currentStudentHasErrors != value)
                {
                    _currentStudentHasErrors = value;
                    RaisePropertyChanged("CurrentStudentHasErrors");
                }
            }
        }

        private bool _currentStudentHasErrors;

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

        private bool _studentListIsEnabled = true;

        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;

        public EnumCollection<StatusEnum> StudentStatusCollection { get; private set; }

        #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()
        {
            // refresh the EnumCollectionView
            StudentStatusCollection.Refresh();
            // synchronize _schoolModel.StudentsList with local cache
            if (_schoolModel != null && _allStudentsCache != null)
                _schoolModel.StudentsList = _allStudentsCache;
            // synchronize _schoolModel.CurrentStudent with local cache
            if (_schoolModel != null && _currentStudentCache != null)
                _schoolModel.CurrentStudent = _currentStudentCache;

            // if CurrentStudentHasErrors, call TryValidate() to push the new
            // error messages into the ValidationSummary
            if (CurrentStudentHasErrors && CurrentStudent != null)
                CurrentStudent.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.StudentsList = null;
                _schoolModel.CurrentStudent = null;
            }
        }

        /// <summary>
        /// Previous Page Command
        /// </summary>
        public RelayCommand PrevPageCommand
        {
            get
            {
                if (_prevPageCommand == null)
                {
                    _prevPageCommand = new RelayCommand(
                        OnPrevPageCommand,
                        () => CanMovePrevPage && !StudentFormInEdit
                              && (_schoolModel != null) && !(_schoolModel.StudentsListHasChanges));
                }
                return _prevPageCommand;
            }
        }

        private RelayCommand _prevPageCommand;

        private void OnPrevPageCommand()
        {
            if (CurrentPage > 1)
            {
                CurrentPage--;
                // get students, apply filter if necessary
                var studentQuery = StudentClientQuery
                    .ApplyClientFilter(_currentFilter)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");
            }
        }

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

        private RelayCommand _nextPageCommand;

        private void OnNextPageCommand()
        {
            CurrentPage++;
            // get students, apply filter if necessary
            var studentQuery = StudentClientQuery
                .ApplyClientFilter(_currentFilter)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");
        }

        /// <summary>
        /// Set Filter Command
        /// </summary>
        public RelayCommand SetFilterCommand
        {
            get
            {
                if (_setFilterCommand == null)
                {
                    _setFilterCommand = new RelayCommand(
                        OnSetFilterCommand,
                        () => !StudentFormInEdit
                              && (_schoolModel != null) && !(_schoolModel.StudentsListHasChanges));
                }
                return _setFilterCommand;
            }
        }

        private RelayCommand _setFilterCommand;

        private void OnSetFilterCommand()
        {
            try
            {
                var message = new NotificationMessageAction<ClientFilter<Student>>(this,
                                                                                   null,
                                                                                   OnFilterCallback);

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

        private void OnFilterCallback(ClientFilter<Student> s)
        {
            _currentFilter = s;
            CurrentPage = 1;
            // get students, apply filter if necessary
            var studentQuery = StudentClientQuery
                .ApplyClientFilter(_currentFilter)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");
        }

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

        private RelayCommand _filterResetCommand;

        private void OnFilterResetCommand()
        {
            // set current filter to order by PersonId
            _currentFilter = new ClientFilter<Student>().OrderBy(n => n.PersonId);
            CurrentPage = 1;
            // get students
            var studentQuery = StudentClientQuery
                .ApplyClientFilter(_currentFilter)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");
        }

        /// <summary>
        /// Default Filter Command
        /// </summary>
        public RelayCommand DefaultFilterCommand
        {
            get
            {
                if (_defaultFilterCommand == null)
                {
                    _defaultFilterCommand = new RelayCommand(
                        OnDefaultFilterCommand,
                        () => _defaultClientFilter != null && !StudentFormInEdit
                              && (_schoolModel != null) && !(_schoolModel.StudentsListHasChanges));
                }
                return _defaultFilterCommand;
            }
        }

        private RelayCommand _defaultFilterCommand;

        private void OnDefaultFilterCommand()
        {
            OnFilterCallback(_defaultClientFilter);
        }

        /// <summary>
        /// Add student command. We can add a new
        /// student when student form is not in edit
        /// </summary>
        public RelayCommand AddStudentCommand
        {
            get
            {
                if (_addStudentCommand == null)
                {
                    _addStudentCommand = new RelayCommand(
                        OnAddStudentCommand,
                        () => !StudentFormInEdit);
                }
                return _addStudentCommand;
            }
        }

        private RelayCommand _addStudentCommand;

        private void OnAddStudentCommand()
        {
            // create a temporary companyId
            int newPersonId = AllStudents.Count > 0
                                  ? ((from student in AllStudents select Math.Abs(student.PersonId)).Max() + 1)*(-1)
                                  : -1;
            // create a new student
            CurrentStudent = new Student
                                 {
                                     SuspendValidation = true,
                                     PersonId = newPersonId,
                                     Name = string.Empty,
                                     EnrollmentDate = DateTime.Now
                                 };
            CurrentStudent.SuspendValidation = false;
            // and begin edit
            OnEditCommitStudentCommand();
        }

        /// <summary>
        /// Delete student command. We can delete a student
        /// when the current student is not null, and student
        ///  form is not in edit
        /// </summary>
        public RelayCommand DeleteStudentCommand
        {
            get
            {
                if (_deleteStudentCommand == null)
                {
                    _deleteStudentCommand = new RelayCommand(
                        OnDeleteStudentCommand,
                        () => (CurrentStudent != null) && !StudentFormInEdit);
                }
                return _deleteStudentCommand;
            }
        }

        private RelayCommand _deleteStudentCommand;

        private void OnDeleteStudentCommand()
        {
            try
            {
                if (CurrentStudent != null && CurrentStudent.Enrollments.Count == 0)
                {
                    // ask to confirm deleting the current student
                    var dialogMessage = new DialogMessage(this,
                                                          SchoolModelResource.DeleteCurrentStudentMessageBoxText,
                                                          OnDeleteStudentCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = SchoolModelResource.ConfirmMessageBoxCaption
                                            };
                    AppMessages.PleaseConfirmMessage.Send(dialogMessage);
                }
                else
                {
                    var dialogMessage = new DialogMessage(this,
                                                          SchoolModelResource
                                                              .CurrentStudentEnrollmentNotEmptyMessageBoxText,
                                                          null)
                                            {
                                                Button = MessageBoxButton.OK,
                                                Caption = SchoolModelResource.WarningMessageBoxCaption
                                            };

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

        private void OnDeleteStudentCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                if (CurrentStudent.ChangeTracker.State == ObjectState.Added)
                {
                    // if State is Added, simply remove from the StudentsList
                    // as the database does not have this record yet
                    AllStudents.Remove(CurrentStudent);
                }
                else
                {
                    // if confirmed, remove current student
                    CurrentStudent.MarkAsDeleted();
                    _schoolModel.SaveStudentChangesAsync(false);
                }
            }
        }

        /// <summary>
        /// Edit/Commit a student. We can edit/commit a student
        /// when current student is not null
        /// </summary>
        public RelayCommand EditCommitStudentCommand
        {
            get
            {
                if (_editCommitStudentCommand == null)
                {
                    _editCommitStudentCommand = new RelayCommand(
                        OnEditCommitStudentCommand,
                        () => (CurrentStudent != null));
                }
                return _editCommitStudentCommand;
            }
        }

        private RelayCommand _editCommitStudentCommand;

        private void OnEditCommitStudentCommand()
        {
            if (CurrentStudent != null)
            {
                if (StudentFormInEdit)
                {
                    // if passed validation, end editing
                    if (!CurrentStudentHasErrors && CurrentStudent.TryValidate())
                    {
                        StudentFormEndEdit();
                        // if this is a new student, add to the StudentsList
                        if (CurrentStudent.ChangeTracker.State == ObjectState.Added)
                        {
                            var alreadyAdded = AllStudents.Any(n => n.PersonId == CurrentStudent.PersonId);
                            if (!alreadyAdded)
                            {
                                AllStudents.Add(CurrentStudent);
                                AllStudentsSource.View.MoveCurrentTo(CurrentStudent);
                            }
                        }
                    }
                }
                else
                {
                    StudentFormBeginEdit();
                }
            }
        }

        /// <summary>
        /// Cancel edit a student. We can cancel edit a student
        /// when current student is not null, and the student form
        /// is currently in edit
        /// </summary>
        public RelayCommand CancelEditStudentCommand
        {
            get
            {
                if (_cancelEditStudentCommand == null)
                {
                    _cancelEditStudentCommand = new RelayCommand(
                        OnCancelEditStudentCommand,
                        () => (CurrentStudent != null) && StudentFormInEdit);
                }
                return _cancelEditStudentCommand;
            }
        }

        private RelayCommand _cancelEditStudentCommand;

        private void OnCancelEditStudentCommand()
        {
            if (CurrentStudent != null)
            {
                StudentFormCancelEdit();
                // if this is a new student, simply discard that record
                if (CurrentStudent.ChangeTracker.State == ObjectState.Added)
                {
                    var alreadyAdded = AllStudents.Any(n => n.PersonId == CurrentStudent.PersonId);
                    if (!alreadyAdded)
                    {
                        CurrentStudent = null;
                        AllStudentsSource.View.MoveCurrentToFirst();
                        if (AllStudentsSource.View.CurrentItem != null)
                            CurrentStudent = (Student) AllStudentsSource.View.CurrentItem;
                    }
                }
            }
        }

        /// <summary>
        /// Refresh current student command. We can refresh
        /// current student when student form is not in edit, 
        /// and there is no change to save for the current 
        ///  student
        /// </summary>
        public RelayCommand RefreshStudentCommand
        {
            get
            {
                if (_refreshStudentCommand == null)
                {
                    _refreshStudentCommand = new RelayCommand(
                        OnRefreshStudentCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && !(_schoolModel.CurrentStudentHasChanges));
                }
                return _refreshStudentCommand;
            }
        }

        private RelayCommand _refreshStudentCommand;

        private void OnRefreshStudentCommand()
        {
            if (CurrentStudent != null)
            {
                _schoolModel.GetStudentByIdAsync(CurrentStudent.PersonId);
            }
        }

        /// <summary>
        /// Submit change command. We can submit changes
        /// when student form is not in edit, and there 
        /// are changes to save for current student
        /// </summary>
        public RelayCommand SubmitStudentChangeCommand
        {
            get
            {
                if (_submitStudentChangeCommand == null)
                {
                    _submitStudentChangeCommand = new RelayCommand(
                        OnSubmitStudentChangeCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && (_schoolModel.CurrentStudentHasChanges));
                }
                return _submitStudentChangeCommand;
            }
        }

        private RelayCommand _submitStudentChangeCommand;

        private void OnSubmitStudentChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy && CurrentStudent != null)
                {
                    // we only save changes when current student passed validation
                    var passedValidation = CurrentStudent.TryValidate();
                    if (!passedValidation) return;

                    // save changes for CurrentStudent only 
                    _schoolModel.SaveStudentChangesAsync(false);
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        /// <summary>
        /// Cancel change command. We can cancel changes
        /// when student form is not in edit, and there 
        /// are changes to cancel for current student
        /// </summary>
        public RelayCommand CancelStudentChangeCommand
        {
            get
            {
                if (_cancelStudentChangeCommand == null)
                {
                    _cancelStudentChangeCommand = new RelayCommand(
                        OnCancelStudentChangeCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && (_schoolModel.CurrentStudentHasChanges));
                }
                return _cancelStudentChangeCommand;
            }
        }

        private RelayCommand _cancelStudentChangeCommand;

        private void OnCancelStudentChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy && CurrentStudent != null)
                {
                    // ask to confirm canceling changes
                    var dialogMessage = new DialogMessage(this,
                                                          SchoolModelResource.CancelAnyChangesMessageBoxText,
                                                          OnCancelStudentChangeCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = SchoolModelResource.ConfirmMessageBoxCaption
                                            };

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

        private void OnCancelStudentChangeCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                // if confirmed, cancel changes for CurrentStudent
                _schoolModel.RejectStudentChanges(false);
            }
        }

        /// <summary>
        /// Refresh students list command. We can
        /// refresh students list when student form is
        /// not in edit, and there is no change to save
        /// </summary>
        public RelayCommand RefreshAllCommand
        {
            get
            {
                if (_refreshAllCommand == null)
                {
                    _refreshAllCommand = new RelayCommand(
                        OnRefreshAllCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && !(_schoolModel.StudentsListHasChanges));
                }
                return _refreshAllCommand;
            }
        }

        private RelayCommand _refreshAllCommand;

        private void OnRefreshAllCommand()
        {
            if (!_schoolModel.IsBusy)
            {
                // get students, apply filter if necessary
                var studentQuery = StudentClientQuery
                    .ApplyClientFilter(_currentFilter)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetStudentsAsync(studentQuery, "StudentPage");
            }
        }

        /// <summary>
        /// Submit change command. We can submit changes
        /// when student form is not in edit, and there are changes to save
        /// </summary>
        public RelayCommand SubmitAllChangeCommand
        {
            get
            {
                if (_submitAllChangeCommand == null)
                {
                    _submitAllChangeCommand = new RelayCommand(
                        OnSubmitAllChangeCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && (_schoolModel.StudentsListHasChanges));
                }
                return _submitAllChangeCommand;
            }
        }

        private RelayCommand _submitAllChangeCommand;

        private void OnSubmitAllChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy)
                {
                    if (AllStudents != null)
                    {
                        // we only save changes when all students passed validation
                        var passedValidation = AllStudents.All(o => o.TryValidate());
                        if (!passedValidation) return;

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

        /// <summary>
        /// Cancel change command. We can cancel changes
        /// when student form is not in edit, and there are changes to cancel
        /// </summary>
        public RelayCommand CancelAllChangeCommand
        {
            get
            {
                if (_cancelAllChangeCommand == null)
                {
                    _cancelAllChangeCommand = new RelayCommand(
                        OnCancelAllChangeCommand,
                        () => !StudentFormInEdit && (_schoolModel != null)
                              && (_schoolModel.StudentsListHasChanges));
                }
                return _cancelAllChangeCommand;
            }
        }

        private RelayCommand _cancelAllChangeCommand;

        private void OnCancelAllChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy)
                {
                    // ask to confirm canceling changes
                    var dialogMessage = new DialogMessage(this,
                                                          SchoolModelResource.CancelAnyChangesMessageBoxText,
                                                          OnCancelAllChangeCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = SchoolModelResource.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 StudentsList
                _schoolModel.RejectStudentChanges();
            }
        }

        #endregion "Public Commands"

        #region "Private Methods"

        private void StudentFormBeginEdit()
        {
            if (CurrentStudent != null)
            {
                CurrentStudent.BeginEdit();
                AppMessages.BeginEditMessage.Send("Student");
                StudentFormInEdit = true;
            }
        }

        private void StudentFormEndEdit()
        {
            AppMessages.EndEditMessage.Send("Student");
            StudentFormInEdit = false;
            if (CurrentStudent != null) CurrentStudent.EndEdit();
        }

        private void StudentFormCancelEdit()
        {
            if (CurrentStudent != null)
            {
                AppMessages.CancelEditMessage.Send("Student");
                StudentFormInEdit = false;
                CurrentStudent.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, "StudentPage")) return;

            if (!e.HasError)
            {
                // clear any previous error after a successful call
                _schoolModel.ClearLastError();

                // cancel any changes before setting AllStudentsSource
                if (_schoolModel.StudentsListHasChanges)
                {
                    _schoolModel.RejectStudentChanges();
                }

                AllStudents = new ObservableCollection<Student>(e.Results);

                AllStudentsSource = new CollectionViewSource {Source = AllStudents};
                AllStudentsSource.View.CurrentChanged += AllStudentsSourceView_CurrentChanged;
                // set CanMovePrevPage and CanMoveNextPage
                CanMovePrevPage = (CurrentPage > 1);
                CanMoveNextPage = (AllStudents.Count == PageSize);

                if (AllStudents.Count >= 1)
                {
                    if (CurrentStudent != null)
                    {
                        var currentStudent = AllStudents
                            .FirstOrDefault(n => n.PersonId == CurrentStudent.PersonId);
                        if (currentStudent != null)
                            AllStudentsSource.View.MoveCurrentTo(currentStudent);
                        else
                            // set the first row as the current student in edit
                            AllStudentsSource.View.MoveCurrentToFirst();
                    }
                    else
                    {
                        // set the first row as the current student in edit
                        AllStudentsSource.View.MoveCurrentToFirst();
                    }
                    CurrentStudent = (Student) AllStudentsSource.View.CurrentItem;
                }
                else
                {
                    CurrentStudent = 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 AllStudentsSourceView_CurrentChanged(object sender, EventArgs e)
        {
            CurrentStudent = (Student) AllStudentsSource.View.CurrentItem;
        }

        /// <summary>
        /// Event handler for GetStudentByIdCompleted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _schoolModel_GetStudentByIdCompleted(object sender, ResultArgs<Student> e)
        {
            if (!e.HasError)
            {
                // clear any previous error after a successful call
                _schoolModel.ClearLastError();

                Student currentStudent = e.Results;
                if (currentStudent != null)
                {
                    // find the matching current student from AllStudents list
                    Student matchedStudent = AllStudents.Single(n => n.PersonId == currentStudent.PersonId);
                    // replace matchedStudent from AllStudents list with what is returned from GetStudentById
                    int index = AllStudents.IndexOf(matchedStudent);
                    AllStudents.Remove(matchedStudent);
                    AllStudents.Insert(index, currentStudent);
                    AllStudentsSource.View.MoveCurrentTo(currentStudent);
                }
                else
                {
                    var dialogMessage = new DialogMessage(this,
                                                          SchoolModelResource.CurrentStudentDoesNotExistMessageBoxText,
                                                          null)
                                            {
                                                Button = MessageBoxButton.OK,
                                                Caption = SchoolModelResource.WarningMessageBoxCaption
                                            };

                    AppMessages.StatusUpdateMessage.Send(dialogMessage);
                }
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        /// <summary>
        /// Event handler for SaveStudentChangesCompleted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _schoolModel_SaveStudentChangesCompleted(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 = SchoolModelResource.WarningMessageBoxCaption
                                            };

                    AppMessages.StatusUpdateMessage.Send(dialogMessage);

                    // If last operation is a delete operation, call reject changes
                    if (CurrentStudent != null && CurrentStudent.ChangeTracker.State == ObjectState.Deleted)
                    {
                        _schoolModel.RejectStudentChanges(false);
                    }
                }
                else
                {
                    if (_schoolModel.StudentsListHasChanges)
                    {
                        if (!_schoolModel.CurrentStudentHasChanges)
                            // only refresh current student after Insert/Update/Delete
                            OnRefreshStudentCommand();
                    }
                    else
                        // refresh the StudentsList 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 "StudentsListHasChanges":
                    RefreshAllCommand.RaiseCanExecuteChanged();
                    SubmitAllChangeCommand.RaiseCanExecuteChanged();
                    CancelAllChangeCommand.RaiseCanExecuteChanged();
                    break;
                case "CurrentStudentHasChanges":
                    RefreshStudentCommand.RaiseCanExecuteChanged();
                    SubmitStudentChangeCommand.RaiseCanExecuteChanged();
                    CancelStudentChangeCommand.RaiseCanExecuteChanged();
                    break;
            }
        }

        /// <summary>
        /// Event handler for PropertyChanged
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StudentPageViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "CurrentStudent":
                    DeleteStudentCommand.RaiseCanExecuteChanged();
                    EditCommitStudentCommand.RaiseCanExecuteChanged();
                    CancelEditStudentCommand.RaiseCanExecuteChanged();
                    break;
                case "StudentFormInEdit":
                    StudentListIsEnabled = !StudentFormInEdit;
                    AddStudentCommand.RaiseCanExecuteChanged();
                    DeleteStudentCommand.RaiseCanExecuteChanged();
                    CancelEditStudentCommand.RaiseCanExecuteChanged();
                    RefreshStudentCommand.RaiseCanExecuteChanged();
                    SubmitStudentChangeCommand.RaiseCanExecuteChanged();
                    CancelStudentChangeCommand.RaiseCanExecuteChanged();
                    RefreshAllCommand.RaiseCanExecuteChanged();
                    SubmitAllChangeCommand.RaiseCanExecuteChanged();
                    CancelAllChangeCommand.RaiseCanExecuteChanged();
                    break;
            }
        }

        /// <summary>
        /// Event handler for GetDefaultFilterByScreenNameCompleted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _schoolModel_GetDefaultFilterByScreenNameCompleted(object sender, ResultArgs<DefaultFilter> e)
        {
            if (!e.HasError)
            {
                // clear any previous error after a successful call
                _schoolModel.ClearLastError();

                if (e.Results != null && e.Results.ScreenName == "StudentPage")
                {
                    _defaultClientFilter = ClientFilter<Student>.Parse(e.Results.Filter);
                }
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        /// <summary>
        /// Event handler for SaveDefaultFilterCompleted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _schoolModel_SaveDefaultFilterCompleted(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 = SchoolModelResource.WarningMessageBoxCaption
                                            };

                    AppMessages.StatusUpdateMessage.Send(dialogMessage);
                }
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        /// <summary>
        /// Message handler for StudentDefaultFilterMessage
        /// </summary>
        /// <param name="clientFilter"></param>
        private void OnStudentDefaultFilterMessage(ClientFilter<Student> clientFilter)
        {
            if (clientFilter != null)
            {
                var defaultFilter = new DefaultFilter
                                        {
                                            ScreenName = "StudentPage",
                                            Filter = clientFilter.ToString()
                                        };
                if (_defaultClientFilter == null) defaultFilter.MarkAsAdded();
                else defaultFilter.MarkAsModified();

                // persist the new default filtering conditions to database
                _schoolModel.SaveDefaultFilterAsync(defaultFilter);
                _defaultClientFilter = clientFilter;
            }
        }

        #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