Click here to Skip to main content
15,885,985 members
Articles / Desktop Programming / XAML

A Sample Silverlight 4 Application Using MEF, MVVM, and WCF RIA Services - Part 1

Rate me:
Please Sign up or sign in to vote.
4.84/5 (108 votes)
7 Jul 2011CPOL9 min read 2.1M   30.9K   298  
Part 1 of a series describing the creation of a Silverlight business application using MEF, MVVM Light, and WCF RIA Services.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using IssueVision.Data.Web;
using IssueVision.Common;

namespace IssueVision.ViewModel
{
    [Export(ViewModelTypes.IssueEditorViewModel, typeof(ViewModelBase))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class IssueEditorViewModel : ViewModelBase
    {
        #region "Private Data Members"
        private IIssueVisionModel _issueVisionModel;
        private Issue _currentIssueCache;
        #endregion "Private Data Members"

        #region "Constructor"
        [ImportingConstructor]
        public IssueEditorViewModel(IIssueVisionModel issueVisionModel)
        {
            _issueVisionModel = issueVisionModel;

            // set up event handling
            _issueVisionModel.GetIssueTypesComplete += new EventHandler<EntityResultsArgs<IssueType>>(_issueVisionModel_GetIssueTypesComplete);
            _issueVisionModel.GetPlatformsComplete += new EventHandler<EntityResultsArgs<Platform>>(_issueVisionModel_GetPlatformsComplete);
            _issueVisionModel.GetResolutionsComplete += new EventHandler<EntityResultsArgs<Resolution>>(_issueVisionModel_GetResolutionsComplete);
            _issueVisionModel.GetStatusesComplete += new EventHandler<EntityResultsArgs<Status>>(_issueVisionModel_GetStatusesComplete);
            _issueVisionModel.GetSubStatusesComplete += new EventHandler<EntityResultsArgs<SubStatus>>(_issueVisionModel_GetSubStatusesComplete);
            _issueVisionModel.GetUsersComplete += new EventHandler<EntityResultsArgs<User>>(_issueVisionModel_GetUsersComplete);

            // set _currentIssueCache to null
            this._currentIssueCache = null;

            // load issue type entries
            IssueTypeEntries = null;
            _issueVisionModel.GetIssueTypesAsync();
            // load platform entries
            PlatformEntries = null;
            _issueVisionModel.GetPlatformsAsync();
            //load resolution entries
            ResolutionEntriesWithNull = null;
            _issueVisionModel.GetResolutionsAsync();
            // load status entries
            StatusEntries = null;
            _issueVisionModel.GetStatusesAsync();
            // load substatus entries
            SubstatusEntriesWithNull = null;
            _issueVisionModel.GetSubStatusesAsync();
            // load user entries
            UserEntries = null;
            UserEntriesWithNull = null;
            _issueVisionModel.GetUsersAsync();

            // register for EditIssueMessage
            AppMessages.EditIssueMessage.Register(this, OnEditIssueMessage);
        }
        #endregion "Constructor"

        #region "ICleanup interface implementation"
        public override void Cleanup()
        {
            if (_issueVisionModel != null)
            {
                // unregister all events
                _issueVisionModel.GetIssueTypesComplete -= new EventHandler<EntityResultsArgs<IssueType>>(_issueVisionModel_GetIssueTypesComplete);
                _issueVisionModel.GetPlatformsComplete -= new EventHandler<EntityResultsArgs<Platform>>(_issueVisionModel_GetPlatformsComplete);
                _issueVisionModel.GetResolutionsComplete -= new EventHandler<EntityResultsArgs<Resolution>>(_issueVisionModel_GetResolutionsComplete);
                _issueVisionModel.GetStatusesComplete -= new EventHandler<EntityResultsArgs<Status>>(_issueVisionModel_GetStatusesComplete);
                _issueVisionModel.GetSubStatusesComplete -= new EventHandler<EntityResultsArgs<SubStatus>>(_issueVisionModel_GetSubStatusesComplete);
                _issueVisionModel.GetUsersComplete -= new EventHandler<EntityResultsArgs<User>>(_issueVisionModel_GetUsersComplete);
                _issueVisionModel = null;
            }
            // set properties back to null
            CurrentIssue = null;
            IssueTypeEntries = null;
            PlatformEntries = null;
            ResolutionEntriesWithNull = null;
            StatusEntries = null;
            SubstatusEntriesWithNull = null;
            UserEntries = null;
            UserEntriesWithNull = null;
            // unregister any messages for this ViewModel
            base.Cleanup();
        }
        #endregion "ICleanup interface implementation"

        #region "Public Properties"

        private Issue _currentIssue;

        public Issue CurrentIssue
        {
            get { return _currentIssue; }
            private set
            {
                if (!ReferenceEquals(_currentIssue, value))
                {
                    _currentIssue = value;
                    this.RaisePropertyChanged("CurrentIssue");
                }
            }
        }

        private IEnumerable<byte> _priorityEntries = null;

        public IEnumerable<byte> PriorityEntries
        {
            get
            {
                if (_priorityEntries == null)
                {
                    List<byte> _priorityList = new List<byte>();
                    for (byte i = IssueVisionServiceConstant.HighestPriority; i <= IssueVisionServiceConstant.LowestPriority; i++)
                    {
                        _priorityList.Add(i);
                    }
                    _priorityEntries = _priorityList.AsEnumerable<byte>();
                }
                return _priorityEntries;
            }
        }

        private IEnumerable<byte> _severityEntries = null;

        public IEnumerable<byte> SeverityEntries
        {
            get
            {
                if (_severityEntries == null)
                {
                    List<byte> _severityList = new List<byte>();
                    for (byte i = IssueVisionServiceConstant.HighestSeverity; i <= IssueVisionServiceConstant.LowestSeverity; i++)
                    {
                        _severityList.Add(i);
                    }
                    _severityEntries = _severityList.AsEnumerable<byte>();
                }
                return _severityEntries;
            }
        }

        private IEnumerable<IssueType> _issueTypeEntries;

        public IEnumerable<IssueType> IssueTypeEntries
        {
            get { return _issueTypeEntries; }
            private set
            {
                if (!ReferenceEquals(_issueTypeEntries, value))
                {
                    _issueTypeEntries = value;
                    this.RaisePropertyChanged("IssueTypeEntries");
                }
            }
        }

        private IEnumerable<Platform> _platformEntries;

        public IEnumerable<Platform> PlatformEntries
        {
            get { return _platformEntries; }
            private set
            {
                if (!ReferenceEquals(_platformEntries, value))
                {
                    _platformEntries = value;
                    this.RaisePropertyChanged("PlatformEntries");
                }
            }
        }

        private IEnumerable<Resolution> _resolutionEntriesWithNull;

        public IEnumerable<Resolution> ResolutionEntriesWithNull
        {
            get { return _resolutionEntriesWithNull; }
            private set
            {
                if (!ReferenceEquals(_resolutionEntriesWithNull, value))
                {
                    _resolutionEntriesWithNull = value;
                    this.RaisePropertyChanged("ResolutionEntriesWithNull");
                }
            }
        }

        private IEnumerable<Status> _statusEntries;

        public IEnumerable<Status> StatusEntries
        {
            get { return _statusEntries; }
            private set
            {
                if (!ReferenceEquals(_statusEntries, value))
                {
                    _statusEntries = value;
                    this.RaisePropertyChanged("StatusEntries");
                }
            }
        }

        private IEnumerable<SubStatus> _substatusEntriesWithNull;

        public IEnumerable<SubStatus> SubstatusEntriesWithNull
        {
            get { return _substatusEntriesWithNull; }
            private set
            {
                if (!ReferenceEquals(_substatusEntriesWithNull, value))
                {
                    _substatusEntriesWithNull = value;
                    this.RaisePropertyChanged("SubstatusEntriesWithNull");
                }
            }
        }

        private IEnumerable<User> _userEntries;

        public IEnumerable<User> UserEntries
        {
            get { return _userEntries; }
            private set
            {
                if (!ReferenceEquals(_userEntries, value))
                {
                    _userEntries = value;
                    this.RaisePropertyChanged("UserEntries");
                }
            }
        }

        private IEnumerable<User> _userEntriesWithNull;

        public IEnumerable<User> UserEntriesWithNull
        {
            get { return _userEntriesWithNull; }
            private set
            {
                if (!ReferenceEquals(_userEntriesWithNull, value))
                {
                    _userEntriesWithNull = value;
                    this.RaisePropertyChanged("UserEntriesWithNull");
                }
            }
        }

        #endregion "Public Properties"

        #region "Public Commands"

        private RelayCommand<DragEventArgs> _handleDropCommand = null;

        public RelayCommand<DragEventArgs> HandleDropCommand
        {
            get
            {
                if (_handleDropCommand == null)
                {
                    _handleDropCommand = new RelayCommand<DragEventArgs>(
                        e => this.OnHandleDropCommand(e),
                        e => this.CurrentIssue != null);
                }
                return _handleDropCommand;
            }
        }

        private void OnHandleDropCommand(DragEventArgs e)
        {
            try
            {
                if (e.Data != null)
                {
                    // get a list of files as FileInfo objects
                    var files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];

                    // loop through the list and read each file
                    foreach (var file in files)
                    {
                        using (var fs = file.OpenRead())
                        using (MemoryStream ms = new MemoryStream())
                        {
                            fs.CopyTo(ms);
                            // and then add each file into the Files entity collection
                            this.CurrentIssue.Files.Add(
                                new Data.Web.File()
                                {
                                    FileID = Guid.NewGuid(),
                                    FileName = file.Name,
                                    Data = ms.GetBuffer()
                                });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private RelayCommand _addFileCommand = null;

        public RelayCommand AddFileCommand
        {
            get
            {
                if (_addFileCommand == null)
                {
                    _addFileCommand = new RelayCommand(
                        () => this.OnAddFileCommand(),
                        () => this.CurrentIssue != null);
                }
                return _addFileCommand;
            }
        }

        private void OnAddFileCommand()
        {
            try
            {
                if (!_issueVisionModel.IsBusy)
                {
                    FileInfo addedFile = null;
                    // ask user for a file to add
                    AppMessages.OpenFileMessage.Send(new NotificationMessageAction<FileInfo>("Open File", g => addedFile = g));

                    if (addedFile != null)
                    {
                        using (var fs = addedFile.OpenRead())
                        using (MemoryStream ms = new MemoryStream())
                        {
                            fs.CopyTo(ms);
                            // and then add the file into the Files entity collection
                            this.CurrentIssue.Files.Add(
                                new Data.Web.File()
                                {
                                    FileID = Guid.NewGuid(),
                                    FileName = addedFile.Name,
                                    Data = ms.GetBuffer()
                                });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private RelayCommand<IssueVision.Data.Web.File> _removeFileCommand = null;

        public RelayCommand<IssueVision.Data.Web.File> RemoveFileCommand
        {
            get
            {
                if (_removeFileCommand == null)
                {
                    _removeFileCommand = new RelayCommand<Data.Web.File>(
                        g => this.OnRemoveFileCommand(g),
                        g => g != null);
                }
                return _removeFileCommand;
            }
        }

        private void OnRemoveFileCommand(Data.Web.File g)
        {
            try
            {
                if (!_issueVisionModel.IsBusy)
                {
                    this.CurrentIssue.Files.Remove(g);
                    this._issueVisionModel.RemoveFile(g);
                }
            }
            catch (Exception ex)
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(ex);
            }
        }

        private RelayCommand<IssueVision.Data.Web.File> _saveToDiskCommand = null;

        public RelayCommand<IssueVision.Data.Web.File> SaveToDiskCommand
        {
            get
            {
                if (_saveToDiskCommand == null)
                {
                    _saveToDiskCommand = new RelayCommand<Data.Web.File>(g =>
                    {
                        if (!_issueVisionModel.IsBusy)
                        {
                            AppMessages.SaveFileMessage.Send(g);
                        }
                    }, g => g != null);
                }
                return _saveToDiskCommand;
            }
        }

        private RelayCommand _addAttributeCommand = null;

        public RelayCommand AddAttributeCommand
        {
            get
            {
                if (_addAttributeCommand == null)
                {
                    _addAttributeCommand = new RelayCommand(
                        () => this.OnAddAttributeCommand(),
                        () => this.CurrentIssue != null);
                }
                return _addAttributeCommand;
            }
        }

        private void OnAddAttributeCommand()
        {
            if (!_issueVisionModel.IsBusy)
            {
                this.CurrentIssue.Attributes.Add(
                    new IssueVision.Data.Web.Attribute()
                    {
                        ID = Guid.NewGuid(),
                        AttributeName = "Key",
                        Value = "Value"
                    });
            }
        }

        private RelayCommand<IssueVision.Data.Web.Attribute> _removeAttributeCommand = null;

        public RelayCommand<IssueVision.Data.Web.Attribute> RemoveAttributeCommand
        {
            get
            {
                if (_removeAttributeCommand == null)
                {
                    _removeAttributeCommand = new RelayCommand<Data.Web.Attribute>(g =>
                    {
                        if (!_issueVisionModel.IsBusy)
                        {
                            this.CurrentIssue.Attributes.Remove(g);
                            this._issueVisionModel.RemoveAttribute(g);
                        }
                    }, g => g != null);
                }
                return _removeAttributeCommand;
            }
        }

        #endregion "Public Commands"

        #region "Private Methods"

        private void _issueVisionModel_GetIssueTypesComplete(object sender, EntityResultsArgs<IssueType> e)
        {
            if (!e.HasError)
            {
                IssueTypeEntries = e.Results.OrderBy(g => g.Name);
                // check whether IssueTypeEntries is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _issueVisionModel_GetPlatformsComplete(object sender, EntityResultsArgs<Platform> e)
        {
            if (!e.HasError)
            {
                PlatformEntries = e.Results.OrderBy(g => g.OS).ThenBy(g => g.OSVersion);
                // check whether PlatformEntries is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _issueVisionModel_GetResolutionsComplete(object sender, EntityResultsArgs<Resolution> e)
        {
            if (!e.HasError)
            {
                // create a new resolution list with the first item of null Name
                List<Resolution> resolutionList = e.Results.ToList<Resolution>();
                resolutionList.Add(new Resolution());
                ResolutionEntriesWithNull = resolutionList.OrderBy(g => g.Name).AsEnumerable<Resolution>();
                // check whether ResolutionEntriesWithNull is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _issueVisionModel_GetStatusesComplete(object sender, EntityResultsArgs<Status> e)
        {
            if (!e.HasError)
            {
                StatusEntries = e.Results.OrderBy(g => g.StatusID);
                // check whether StatusEntries is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _issueVisionModel_GetSubStatusesComplete(object sender, EntityResultsArgs<SubStatus> e)
        {
            if (!e.HasError)
            {
                // create a new substatus list with the first item of null Name
                List<SubStatus> substatusList = e.Results.ToList<SubStatus>();
                substatusList.Add(new SubStatus());
                SubstatusEntriesWithNull = substatusList.OrderBy(g => g.Name).AsEnumerable<SubStatus>();
                // check whether SubstatusEntriesWithNull is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _issueVisionModel_GetUsersComplete(object sender, EntityResultsArgs<User> e)
        {
            if (!e.HasError)
            {
                UserEntries = e.Results.OrderBy(g => g.Name);
                // create a new user list with the first item of null user name
                List<User> userList = e.Results.ToList<User>();
                userList.Add(new User());
                UserEntriesWithNull = userList.OrderBy(g => g.Name).AsEnumerable<User>();
                // check whether UserEntries/UserEntriesWithNull is populated after CurrentIssue
                this.AssignCurrentIssue(null);
            }
            else
            {
                // notify user if there is any error
                AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void OnEditIssueMessage(Issue editIssue)
        {
            if (editIssue != null)
            {
                // check whether this issue is read-only or not
                if (editIssue.IsIssueReadOnly())
                    AppMessages.ReadOnlyIssueMessage.Send(true);
                else
                    AppMessages.ReadOnlyIssueMessage.Send(false);

                this.AssignCurrentIssue(editIssue);
            }
        }

        /// <summary>
        /// Assign edit issue only after all ComboBox are ready
        /// </summary>
        /// <param name="editIssue"></param>
        private void AssignCurrentIssue(Issue editIssue)
        {
            if (editIssue != null)
            {
                // this call is coming from OnEditIssueMessage()
                if (IssueTypeEntries != null && PlatformEntries != null &&
                    ResolutionEntriesWithNull != null && StatusEntries != null &&
                    SubstatusEntriesWithNull != null && UserEntries != null &&
                    UserEntriesWithNull != null)
                {
                    // if all ComboBox are ready, we set CurrentIssue
                    this.CurrentIssue = editIssue;
                    this._currentIssueCache = null;
                }
                else
                    this._currentIssueCache = editIssue;
            }
            else
            {
                // this call is coming from one of the complete event handlers
                if (this._currentIssueCache != null && IssueTypeEntries != null && 
                    PlatformEntries != null && ResolutionEntriesWithNull != null &&
                    StatusEntries != null && SubstatusEntriesWithNull != null &&
                    UserEntries != null && UserEntriesWithNull != null)
                {
                    // if all ComboBox are ready, we set CurrentIssue
                    this.CurrentIssue = _currentIssueCache;
                    this._currentIssueCache = null;
                } 
            }
        }

        #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