Mercurial > silverbladetech
view Chronosv2/source/Presentation/ViewModel/WindowViewModel.cs @ 19:09d18d6e5f40
airport work
author | stevenh7776 stevenhollidge@hotmail.com |
---|---|
date | Thu, 15 Mar 2012 06:59:15 +0000 |
parents | 443821e55f06 |
children |
line wrap: on
line source
using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using Chronos.Presentation.Core.ViewModel; using Chronos.Presentation.Core.Windows; using NLog; using nRoute.Components; namespace Chronos.Presentation.ViewModel { public abstract class WindowViewModel<TEntity> : NavigationViewModel, IWindowViewModel where TEntity: class, new() { #region · Logger · private static Logger Logger = LogManager.GetCurrentClassLogger(); #endregion #region · Inner Types · [Serializable] protected enum InquiryActionResultType { DataFetched, RequestedNew, DataNotFound } protected sealed class InquiryActionResult<TResult> where TResult : class { #region · Properties · public TResult Data { get; set; } public InquiryActionResultType Result { get; set; } #endregion #region · Constructors · public InquiryActionResult() { } #endregion } #endregion #region · PropertyChangedEventArgs Cached Instances · private static readonly PropertyChangedEventArgs ViewModeChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.ViewMode); private static readonly PropertyChangedEventArgs StatusMessageChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.StatusMessage); private static readonly PropertyChangedEventArgs NotificationMessageChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.NotificationMessage); #endregion #region · Events · /// <summary> /// Occurs when view mode is changed. /// </summary> public event EventHandler ViewModeChanged; #endregion #region · Fields · private TEntity originalEntity; private string statusMessage; private string notificationMessage; private TEntity entity; private ViewModeType viewMode; private PropertyStateCollection<TEntity> propertyStates; #region · Commands · private ActionCommand inquiryCommand; #endregion #endregion #region · Properties · /// <summary> /// Gets the property state collection /// </summary> public PropertyStateCollection<TEntity> PropertyStates { get { if (this.propertyStates == null) { this.propertyStates = new PropertyStateCollection<TEntity>(); } return this.propertyStates; } } /// <summary> /// Gets or sets the state of the smart part. /// </summary> /// <value>The state of the smart part.</value> public ViewModeType ViewMode { get { return this.viewMode; } set { if (this.viewMode != value) { this.viewMode = value; try { this.OnViewModeChanged(); } catch { #warning TODO: This is done to prevent DataGrid erroros when discarding changes on new records } } } } /// <summary> /// Gets the inquiry data command /// </summary> public ActionCommand InquiryCommand { get { if (this.inquiryCommand == null) { this.inquiryCommand = new ActionCommand ( () => OnInquiryData(), () => CanInquiryData() ); } return this.inquiryCommand; } } /// <summary> /// Gets or sets the status message text /// </summary> public string StatusMessage { get { return this.statusMessage; } set { if (this.statusMessage != value) { this.statusMessage = value; this.NotifyPropertyChanged(StatusMessageChangedArgs); } } } /// <summary> /// Gets or sets the notification message text /// </summary> public string NotificationMessage { get { return this.notificationMessage; } set { if (this.notificationMessage != value) { this.notificationMessage = value; this.NotifyPropertyChanged(NotificationMessageChangedArgs); } } } #endregion #region · Protected Properties · /// <summary> /// Gets or sets the data model. /// </summary> /// <value>The data model.</value> protected TEntity Entity { get { return this.entity; } private set { if (!Object.ReferenceEquals(this.entity, value)) { this.entity = value; } } } protected TEntity OriginalEntity { get { return this.originalEntity; } set { this.originalEntity = value; } } #endregion #region · Constructors · protected WindowViewModel() : base() { this.InitializePropertyStates(); this.Entity = new TEntity(); this.ViewMode = ViewModeType.ViewOnly; } #endregion #region · Command Actions · #region · Inquiry · protected virtual bool CanInquiryData() { return (this.ViewMode == ViewModeType.ViewOnly); } protected void OnInquiryData() { InquiryActionResult<TEntity> result = new InquiryActionResult<TEntity> { Result = InquiryActionResultType.DataNotFound }; this.ViewMode = ViewModeType.Busy; this.StatusMessage = "Obteniendo datos, espere por favor ..."; Task task = Task.Factory.StartNew ( (o) => { Logger.Debug("Obteniendo datos '{0}'", this.Entity.ToString()); this.OnInquiryAction(result); }, result ); task.ContinueWith ( (t) => { Logger.Debug("Error al obtener datos '{0}'", t.Exception.InnerException.ToString()); this.OnInquiryActionFailed(); Exception exception = null; this.OriginalEntity = null; if (t.Exception.InnerException != null) { exception = t.Exception.InnerException; } else { exception = t.Exception; } this.NotificationMessage = exception.Message; }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent, TaskScheduler.FromCurrentSynchronizationContext() ); task.ContinueWith ( _ => { Logger.Debug("Datos obtenidos correctamente '{0}'", this.Entity.ToString()); this.StatusMessage = null; this.OnInquiryActionComplete(result); }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent, TaskScheduler.FromCurrentSynchronizationContext() ); } protected abstract void OnInquiryAction(InquiryActionResult<TEntity> result); protected virtual void OnInquiryActionComplete(InquiryActionResult<TEntity> result) { switch (result.Result) { case InquiryActionResultType.DataNotFound: this.OriginalEntity = null; this.ResetDataModel(); this.ViewMode = ViewModeType.ViewOnly; break; case InquiryActionResultType.RequestedNew: throw new InvalidOperationException("Requested New is not valid on this type of ViewModel"); case InquiryActionResultType.DataFetched: this.ResetDataModel(result.Data); this.OriginalEntity = this.entity; this.ViewMode = ViewModeType.ViewOnly; break; } } protected virtual void OnInquiryActionFailed() { this.ViewMode = ViewModeType.ViewOnly; } #endregion #endregion #region · Overriden Methods · /// <summary> /// Called when the related view is being closed. /// </summary> public override void Close() { Logger.Debug("Cerrar ventana '{0}'", this.GetType()); if (this.originalEntity != null) { this.originalEntity = null; } if (this.entity != null) { this.entity = null; } if (this.propertyStates != null) { this.propertyStates.Clear(); this.propertyStates = null; } this.inquiryCommand = null; this.statusMessage = null; this.notificationMessage = null; base.Close(); } #endregion #region · DataModel Reset Methods · protected void ResetDataModel() { Logger.Debug("Resetar model '{0}'", this.GetType()); this.ResetDataModel(new TEntity()); Logger.Debug("Model reseteado '{0}'", this.GetType()); } protected virtual void ResetDataModel(TEntity model) { this.OnResetingDataModel(this.Entity, model); this.OriginalEntity = null; this.Entity = model; this.OnResetedDataModel(model); } protected virtual void OnResetingDataModel(TEntity oldModel, TEntity newModel) { } protected virtual void OnResetedDataModel(TEntity newModel) { this.NotifyAllPropertiesChanged(); } #endregion #region · Protected Methods · protected virtual void InitializePropertyStates() { } protected virtual void OnViewModeChanged() { if (this.ViewModeChanged != null) { this.ViewModeChanged(this, new EventArgs()); } this.NotifyPropertyChanged(ViewModeChangedArgs); } protected virtual void UpdateAllowedUserActions() { this.Invoke ( () => { this.InquiryCommand.RequeryCanExecute(); } ); } protected override void NotifyPropertyChanged(PropertyChangedEventArgs args) { if (args != StatusMessageChangedArgs) { this.StatusMessage = null; } if (args != NotificationMessageChangedArgs) { this.NotificationMessage = null; } this.UpdateAllowedUserActions(); base.NotifyPropertyChanged(args); } #endregion } }