Click here to Skip to main content
15,889,808 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.6K   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.InstructorPageViewModel, typeof (ViewModelBase))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class InstructorPageViewModel : 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 InstructorPageViewModel(ISchoolModel schoolModel)
        {
            _schoolModel = schoolModel;

            // set up event handling
            _schoolModel.PropertyChanged += _schoolModel_PropertyChanged;
            _schoolModel.GetInstructorsCompleted += _schoolModel_GetInstructorsCompleted;
            _schoolModel.GetInstructorByIdCompleted += _schoolModel_GetInstructorByIdCompleted;
            _schoolModel.SaveInstructorChangesCompleted += _schoolModel_SaveInstructorChangesCompleted;

            PropertyChanged += InstructorPageViewModel_PropertyChanged;

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

            // set current page
            CurrentPage = 1;

            // get instructors
            var instructorQuery = ClientQuerySet.Instructors.Include("Courses")
                .OrderBy(n => n.PersonId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");

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

        #endregion "Constructor"

        #region "Public Properties"

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

        private ObservableCollection<Instructor> _allInstructorsCache;

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

        private CollectionViewSource _allInstructorsSource;

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

        private Instructor _currentInstructorCache;

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

        private bool _instructorFormInEdit;

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

        private bool _currentInstructorHasErrors;

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

        private bool _instructorListIsEnabled = 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> InstructorStatusCollection { 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
            InstructorStatusCollection.Refresh();
            // synchronize _schoolModel.InstructorsList with local cache
            if (_schoolModel != null && _allInstructorsCache != null)
                _schoolModel.InstructorsList = _allInstructorsCache;
            // synchronize _schoolModel.CurrentInstructor with local cache
            if (_schoolModel != null && _currentInstructorCache != null)
                _schoolModel.CurrentInstructor = _currentInstructorCache;

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

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

        private RelayCommand _prevPageCommand;

        private void OnPrevPageCommand()
        {
            if (CurrentPage > 1)
            {
                CurrentPage--;
                // get instructors
                var query = ClientQuerySet.Instructors.Include("Courses");
                // apply filter if necessary
                if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Name.Contains(_filter));
                var instructorQuery = query.OrderBy(n => n.PersonId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");
            }
        }

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

        private RelayCommand _nextPageCommand;

        private void OnNextPageCommand()
        {
            CurrentPage++;
            // get instructors
            var query = ClientQuerySet.Instructors.Include("Courses");
            // apply filter if necessary
            if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Name.Contains(_filter));
            var instructorQuery = query.OrderBy(n => n.PersonId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");
        }

        /// <summary>
        /// Filter Name Command
        /// </summary>
        public RelayCommand FilterNameCommand
        {
            get
            {
                if (_filterNameCommand == null)
                {
                    _filterNameCommand = new RelayCommand(
                        OnFilterNameCommand,
                        () => !InstructorFormInEdit
                              && (_schoolModel != null) && !(_schoolModel.InstructorsListHasChanges));
                }
                return _filterNameCommand;
            }
        }

        private RelayCommand _filterNameCommand;

        private void OnFilterNameCommand()
        {
            try
            {
                var message = new NotificationMessageAction<string>(this,
                                                                    ApplicationStrings.FilterOnNameText,
                                                                    OnFilterNameCallback);

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

        private void OnFilterNameCallback(string s)
        {
            _filter = s;
            CurrentPage = 1;
            // get instructors
            var query = ClientQuerySet.Instructors.Include("Courses");
            // apply filter if necessary
            if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Name.Contains(_filter));
            var instructorQuery = query.OrderBy(n => n.PersonId)
                .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                .AsClientQuery();
            _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");
        }

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

        private RelayCommand _filterResetCommand;

        private void OnFilterResetCommand()
        {
            if (!string.IsNullOrWhiteSpace(_filter))
            {
                _filter = string.Empty;
                CurrentPage = 1;
                // get instructors
                var instructorQuery = ClientQuerySet.Instructors.Include("Courses")
                    .OrderBy(n => n.PersonId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");
            }
        }

        /// <summary>
        /// Add instructor command. We can add a new
        /// instructor when instructor form is not in edit
        /// </summary>
        public RelayCommand AddInstructorCommand
        {
            get
            {
                if (_addInstructorCommand == null)
                {
                    _addInstructorCommand = new RelayCommand(
                        OnAddInstructorCommand,
                        () => !InstructorFormInEdit);
                }
                return _addInstructorCommand;
            }
        }

        private RelayCommand _addInstructorCommand;

        private void OnAddInstructorCommand()
        {
            // create a temporary companyId
            int newPersonId = AllInstructors.Count > 0
                                  ? ((from instructor in AllInstructors select Math.Abs(instructor.PersonId)).Max() + 1)*
                                    (-1)
                                  : -1;
            // create a new instructor
            CurrentInstructor = new Instructor
                                    {
                                        SuspendValidation = true,
                                        PersonId = newPersonId,
                                        Name = string.Empty,
                                        HireDate = DateTime.Now,
                                        Salary = null
                                    };
            CurrentInstructor.SuspendValidation = false;
            // and begin edit
            OnEditCommitInstructorCommand();
        }

        /// <summary>
        /// Delete instructor command. We can delete a instructor
        /// when the current instructor is not null, and instructor
        ///  form is not in edit
        /// </summary>
        public RelayCommand DeleteInstructorCommand
        {
            get
            {
                if (_deleteInstructorCommand == null)
                {
                    _deleteInstructorCommand = new RelayCommand(
                        OnDeleteInstructorCommand,
                        () => (CurrentInstructor != null) && !InstructorFormInEdit);
                }
                return _deleteInstructorCommand;
            }
        }

        private RelayCommand _deleteInstructorCommand;

        private void OnDeleteInstructorCommand()
        {
            try
            {
                if (CurrentInstructor != null && CurrentInstructor.Courses.Count == 0)
                {
                    // ask to confirm deleting the current instructor
                    var dialogMessage = new DialogMessage(this,
                                                          ApplicationStrings.DeleteCurrentInstructorMessageBoxText,
                                                          OnDeleteInstructorCallback)
                                            {
                                                Button = MessageBoxButton.OKCancel,
                                                Caption = ApplicationStrings.ConfirmMessageBoxCaption
                                            };

                    AppMessages.PleaseConfirmMessage.Send(dialogMessage);
                }
                else
                {
                    var dialogMessage = new DialogMessage(this,
                                                          ErrorResources.CurrentInstructorCourseNotEmptyMessageBoxText,
                                                          null)
                                            {
                                                Button = MessageBoxButton.OK,
                                                Caption = ApplicationStrings.WarningMessageBoxCaption
                                            };

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

        private void OnDeleteInstructorCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                if (CurrentInstructor.ChangeTracker.State == ObjectState.Added)
                {
                    // if State is Added, simply remove from the InstructorsList
                    // as the database does not have this record yet
                    AllInstructors.Remove(CurrentInstructor);
                }
                else
                {
                    // if confirmed, remove current instructor
                    CurrentInstructor.MarkAsDeleted();
                    _schoolModel.SaveInstructorChangesAsync(false);
                }
            }
        }

        /// <summary>
        /// Edit/Commit a instructor. We can edit/commit a instructor
        /// when current instructor is not null
        /// </summary>
        public RelayCommand EditCommitInstructorCommand
        {
            get
            {
                if (_editCommitInstructorCommand == null)
                {
                    _editCommitInstructorCommand = new RelayCommand(
                        OnEditCommitInstructorCommand,
                        () => (CurrentInstructor != null));
                }
                return _editCommitInstructorCommand;
            }
        }

        private RelayCommand _editCommitInstructorCommand;

        private void OnEditCommitInstructorCommand()
        {
            if (CurrentInstructor != null)
            {
                if (InstructorFormInEdit)
                {
                    // if passed validation, end editing
                    if (!CurrentInstructorHasErrors && CurrentInstructor.TryValidate())
                    {
                        InstructorFormEndEdit();
                        // if this is a new instructor, add to the InstructorsList
                        if (CurrentInstructor.ChangeTracker.State == ObjectState.Added)
                        {
                            var alreadyAdded = AllInstructors.Any(n => n.PersonId == CurrentInstructor.PersonId);
                            if (!alreadyAdded)
                            {
                                AllInstructors.Add(CurrentInstructor);
                                AllInstructorsSource.View.MoveCurrentTo(CurrentInstructor);
                            }
                        }
                    }
                }
                else
                {
                    InstructorFormBeginEdit();
                }
            }
        }

        /// <summary>
        /// Cancel edit a instructor. We can cancel edit a instructor
        /// when current instructor is not null, and the instructor form
        /// is currently in edit
        /// </summary>
        public RelayCommand CancelEditInstructorCommand
        {
            get
            {
                if (_cancelEditInstructorCommand == null)
                {
                    _cancelEditInstructorCommand = new RelayCommand(
                        OnCancelEditInstructorCommand,
                        () => (CurrentInstructor != null) && InstructorFormInEdit);
                }
                return _cancelEditInstructorCommand;
            }
        }

        private RelayCommand _cancelEditInstructorCommand;

        private void OnCancelEditInstructorCommand()
        {
            if (CurrentInstructor != null)
            {
                InstructorFormCancelEdit();
                // if this is a new instructor, simply discard that record
                if (CurrentInstructor.ChangeTracker.State == ObjectState.Added)
                {
                    var alreadyAdded = AllInstructors.Any(n => n.PersonId == CurrentInstructor.PersonId);
                    if (!alreadyAdded)
                    {
                        CurrentInstructor = null;
                        AllInstructorsSource.View.MoveCurrentToFirst();
                        if (AllInstructorsSource.View.CurrentItem != null)
                            CurrentInstructor = (Instructor) AllInstructorsSource.View.CurrentItem;
                    }
                }
            }
        }

        /// <summary>
        /// Refresh current instructor command. We can refresh
        /// current instructor when instructor form is not in edit, 
        /// and there is no change to save for the current 
        ///  instructor
        /// </summary>
        public RelayCommand RefreshInstructorCommand
        {
            get
            {
                if (_refreshInstructorCommand == null)
                {
                    _refreshInstructorCommand = new RelayCommand(
                        OnRefreshInstructorCommand,
                        () => !InstructorFormInEdit && (_schoolModel != null)
                              && !(_schoolModel.CurrentInstructorHasChanges));
                }
                return _refreshInstructorCommand;
            }
        }

        private RelayCommand _refreshInstructorCommand;

        private void OnRefreshInstructorCommand()
        {
            if (CurrentInstructor != null)
            {
                _schoolModel.GetInstructorByIdAsync(CurrentInstructor.PersonId);
            }
        }

        /// <summary>
        /// Submit change command. We can submit changes
        /// when instructor form is not in edit, and there 
        /// are changes to save for current instructor
        /// </summary>
        public RelayCommand SubmitInstructorChangeCommand
        {
            get
            {
                if (_submitInstructorChangeCommand == null)
                {
                    _submitInstructorChangeCommand = new RelayCommand(
                        OnSubmitInstructorChangeCommand,
                        () => !InstructorFormInEdit && (_schoolModel != null)
                              && (_schoolModel.CurrentInstructorHasChanges));
                }
                return _submitInstructorChangeCommand;
            }
        }

        private RelayCommand _submitInstructorChangeCommand;

        private void OnSubmitInstructorChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy && CurrentInstructor != null)
                {
                    // we only save changes when current instructor passed validation
                    var passedValidation = CurrentInstructor.TryValidateObjectGraph();
                    if (!passedValidation) return;

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

        /// <summary>
        /// Cancel change command. We can cancel changes
        /// when instructor form is not in edit, and there 
        /// are changes to cancel for current instructor
        /// </summary>
        public RelayCommand CancelInstructorChangeCommand
        {
            get
            {
                if (_cancelInstructorChangeCommand == null)
                {
                    _cancelInstructorChangeCommand = new RelayCommand(
                        OnCancelInstructorChangeCommand,
                        () => !InstructorFormInEdit && (_schoolModel != null)
                              && (_schoolModel.CurrentInstructorHasChanges));
                }
                return _cancelInstructorChangeCommand;
            }
        }

        private RelayCommand _cancelInstructorChangeCommand;

        private void OnCancelInstructorChangeCommand()
        {
            try
            {
                if (!_schoolModel.IsBusy && CurrentInstructor != null)
                {
                    // ask to confirm canceling changes
                    var dialogMessage = new DialogMessage(this,
                                                          ApplicationStrings.CancelAnyChangesMessageBoxText,
                                                          OnCancelInstructorCallback)
                                            {
                                                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 OnCancelInstructorCallback(MessageBoxResult s)
        {
            if (s == MessageBoxResult.OK)
            {
                // if confirmed, cancel changes for CurrentInstructor
                _schoolModel.RejectInstructorChanges(false);
            }
        }

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

        private RelayCommand _refreshAllCommand;

        private void OnRefreshAllCommand()
        {
            if (!_schoolModel.IsBusy)
            {
                // get instructors
                var query = ClientQuerySet.Instructors.Include("Courses");
                // apply filter if necessary
                if (!string.IsNullOrWhiteSpace(_filter)) query = query.Where(n => n.Name.Contains(_filter));
                var instructorQuery = query.OrderBy(n => n.PersonId)
                    .Skip((CurrentPage - 1)*PageSize).Take(PageSize)
                    .AsClientQuery();
                _schoolModel.GetInstructorsAsync(instructorQuery, "InstructorPage");
            }
        }

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

        private RelayCommand _submitAllChangeCommand;

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

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

        /// <summary>
        /// Cancel change command. We can cancel changes
        /// when instructor form is not in edit, and there are changes to cancel
        /// </summary>
        public RelayCommand CancelAllChangeCommand
        {
            get
            {
                if (_cancelAllChangeCommand == null)
                {
                    _cancelAllChangeCommand = new RelayCommand(
                        OnCancelAllChangeCommand,
                        () => !InstructorFormInEdit && (_schoolModel != null)
                              && (_schoolModel.InstructorsListHasChanges));
                }
                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 InstructorsList
                _schoolModel.RejectInstructorChanges();
            }
        }

        #endregion "Public Commands"

        #region "Private Methods"

        private void InstructorFormBeginEdit()
        {
            if (CurrentInstructor != null)
            {
                CurrentInstructor.BeginEdit();
                AppMessages.BeginEditMessage.Send("Instructor");
                InstructorFormInEdit = true;
            }
        }

        private void InstructorFormEndEdit()
        {
            AppMessages.EndEditMessage.Send("Instructor");
            InstructorFormInEdit = false;
            if (CurrentInstructor != null) CurrentInstructor.EndEdit();
        }

        private void InstructorFormCancelEdit()
        {
            if (CurrentInstructor != null)
            {
                AppMessages.CancelEditMessage.Send("Instructor");
                InstructorFormInEdit = false;
                CurrentInstructor.CancelEdit();
            }
        }

        /// <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, "InstructorPage")) return;

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

                // cancel any changes before setting AllInstructorsSource
                if (_schoolModel.InstructorsListHasChanges)
                {
                    _schoolModel.RejectInstructorChanges();
                }

                AllInstructors = new ObservableCollection<Instructor>(e.Results);

                AllInstructorsSource = new CollectionViewSource {Source = AllInstructors};
                // sort by instructor Id
                AllInstructorsSource.SortDescriptions.Add(new SortDescription("PersonId", ListSortDirection.Ascending));
                AllInstructorsSource.View.CurrentChanged += AllInstructorsSourceView_CurrentChanged;
                // set CanMovePrevPage and CanMoveNextPage
                CanMovePrevPage = (CurrentPage > 1);
                CanMoveNextPage = (AllInstructors.Count == PageSize);

                if (AllInstructors.Count >= 1)
                {
                    if (CurrentInstructor != null)
                    {
                        var currentInstructor = AllInstructors
                            .FirstOrDefault(n => n.PersonId == CurrentInstructor.PersonId);
                        if (currentInstructor != null)
                            AllInstructorsSource.View.MoveCurrentTo(currentInstructor);
                        else
                            // set the first row as the current instructor in edit
                            AllInstructorsSource.View.MoveCurrentToFirst();
                    }
                    else
                    {
                        // set the first row as the current instructor in edit
                        AllInstructorsSource.View.MoveCurrentToFirst();
                    }
                    CurrentInstructor = (Instructor) AllInstructorsSource.View.CurrentItem;
                }
                else
                {
                    CurrentInstructor = 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 AllInstructorsSourceView_CurrentChanged(object sender, EventArgs e)
        {
            CurrentInstructor = (Instructor) AllInstructorsSource.View.CurrentItem;
        }

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

                Instructor currentInstructor = e.Results;
                if (currentInstructor != null)
                {
                    // find the matching current instructor from AllInstructors list
                    Instructor matchedInstructor = AllInstructors.Single(n => n.PersonId == currentInstructor.PersonId);
                    // replace matchedInstructor from AllInstructors list with what is returned from GetInstructorById
                    int index = AllInstructors.IndexOf(matchedInstructor);
                    AllInstructors.Remove(matchedInstructor);
                    AllInstructors.Insert(index, currentInstructor);
                    AllInstructorsSource.View.MoveCurrentTo(currentInstructor);
                }
                else
                {
                    var dialogMessage = new DialogMessage(this,
                                                          ErrorResources.CurrentInstructorDoesNotExistMessageBoxText,
                                                          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 SaveInstructorChangesCompleted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _schoolModel_SaveInstructorChangesCompleted(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 (CurrentInstructor != null && CurrentInstructor.ChangeTracker.State == ObjectState.Deleted)
                    {
                        _schoolModel.RejectInstructorChanges(false);
                    }
                }
                else
                {
                    if (_schoolModel.InstructorsListHasChanges)
                    {
                        if (!_schoolModel.CurrentInstructorHasChanges)
                            // only refresh current instructor after Insert/Update/Delete
                            OnRefreshInstructorCommand();
                    }
                    else
                        // refresh the InstructorsList 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 "InstructorsListHasChanges":
                    RefreshAllCommand.RaiseCanExecuteChanged();
                    SubmitAllChangeCommand.RaiseCanExecuteChanged();
                    CancelAllChangeCommand.RaiseCanExecuteChanged();
                    break;
                case "CurrentInstructorHasChanges":
                    RefreshInstructorCommand.RaiseCanExecuteChanged();
                    SubmitInstructorChangeCommand.RaiseCanExecuteChanged();
                    CancelInstructorChangeCommand.RaiseCanExecuteChanged();
                    break;
            }
        }

        /// <summary>
        /// Event handler for PropertyChanged
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InstructorPageViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "CurrentInstructor":
                    DeleteInstructorCommand.RaiseCanExecuteChanged();
                    EditCommitInstructorCommand.RaiseCanExecuteChanged();
                    CancelEditInstructorCommand.RaiseCanExecuteChanged();
                    break;
                case "InstructorFormInEdit":
                    InstructorListIsEnabled = !InstructorFormInEdit;
                    AddInstructorCommand.RaiseCanExecuteChanged();
                    DeleteInstructorCommand.RaiseCanExecuteChanged();
                    CancelEditInstructorCommand.RaiseCanExecuteChanged();
                    RefreshInstructorCommand.RaiseCanExecuteChanged();
                    SubmitInstructorChangeCommand.RaiseCanExecuteChanged();
                    CancelInstructorChangeCommand.RaiseCanExecuteChanged();
                    RefreshAllCommand.RaiseCanExecuteChanged();
                    SubmitAllChangeCommand.RaiseCanExecuteChanged();
                    CancelAllChangeCommand.RaiseCanExecuteChanged();
                    break;
            }
        }

        #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