using Common.Infrastructure.Commands; using Common.Infrastructure.Ioc; using Common.Infrastructure.Messaging; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using System; using System.Windows.Forms; using System.Windows.Input; using mag = Magellan.Framework; namespace Common.Infrastructure.ViewModels { public abstract class CoreViewModel : ViewModelBase, ISupportMessageTokens, mag.IViewAware { private IMessengerCore _messenger; public IMessengerCore Messenger { get { if (_messenger == null) { _messenger = TypeResolver.Get(); } return _messenger; } set { _messenger = value; } } protected virtual ICommand FileDialog(string dialogTitle, Action handleFileName) { return new FileDialogCommand(dialogTitle, handleFileName); } #region DoWork public void DoWork(Action activity) { Action onComplete = null; Action onError = null; DoWork(activity, onComplete, onError); } public void DoWork(Action activity, Action onComplete, Action onError) { var cmd = WorkCommand(activity, null, onComplete, onError); cmd.Execute(null); } #endregion #region WorkCommand public ICommand WorkCommand(Action activity) { Predicate canExecute = null; Action onComplete = null; Action onError = null; return WorkCommand(activity, canExecute, onComplete, onError); } public ICommand WorkCommand(Action activity, Predicate canExecute) { Action onComplete = null; Action onError = null; return WorkCommand(activity, canExecute, onComplete, onError); } public ICommand WorkCommand(Action activity, Predicate canExecute, Action onComplete, Action onError) { var key = Guid.NewGuid().ToString(); var internalActivity = new Action( p => { Messenger.Send(new BusyMessage(key, true), MessageToken); activity(p); }); var internalOnComplete = new Action( p => { if (onComplete != null) onComplete(p); Messenger.Send(new BusyMessage(key, false), MessageToken); }); return new AsynchronousCommand(internalActivity, canExecute, internalOnComplete, onError); } public ICommand WorkCommand(Action activity, Action onComplete) { Func canExecute = null; Action onError = null; return WorkCommand(activity, canExecute, onComplete, onError); } public ICommand WorkCommand(Action activity) { Func canExecute = null; Action onComplete = null; Action onError = null; return WorkCommand(activity, canExecute, onComplete, onError); } public ICommand WorkCommand(Action activity, Func canExecute) { Action onComplete = null; Action onError = null; return WorkCommand(activity, canExecute, onComplete, onError); } public ICommand WorkCommand(Action activity, Func canExecute, Action onComplete, Action onError) { var key = Guid.NewGuid().ToString(); var internalActivity = new Action( () => { Messenger.Send(new BusyMessage(key, true), MessageToken); activity(); }); var internalOnComplete = new Action( () => { if (onComplete != null) onComplete(); Messenger.Send(new BusyMessage(key, false), MessageToken); }); return new AsynchronousCommand(internalActivity, canExecute, internalOnComplete, onError); } #endregion /// /// Represents a confirm dialog displayed to the user. /// /// The message displayed to the user. /// The action to perform when the user choose Yes in the confirm dialog and looks like this: () => DoSomething() /// public ICommand ConfirmCommand(string message, Action yesAction) { //var internalYesAction = new Action(() => DoWork(yesAction)); return new ConfirmCommand(MessageToken, message, yesAction); } public void MessageBox(string content) { new MessageBoxCommand(content, MessageToken).Execute(null); } public ICommand MessageBoxCommand(string content) { return new MessageBoxCommand(content, MessageToken); } public ICommand DialogCommand(string content) { return new MessageBoxCommand(content, MessageToken); } protected virtual ICommand NavigateCommand(Func message, Predicate canExecute) { return new NavigateCommand(MessageToken, message, canExecute); } protected virtual ICommand NavigateCommand(string controller, string action, object routeValues, NavigationDirections direction, Predicate canExecute) { return new NavigateCommand(MessageToken, controller, action, routeValues, direction, canExecute); } protected virtual void Navigate(string controller, string action) { new NavigateCommand(controller, action, null, NavigationDirections.Forward, MessageToken).Execute(null); } /// /// Navigates the command. /// /// The controller. /// The action. /// /// Defines the method that determines whether the command can execute in its current state. /// Returns true if this command can be executed; otherwise, false. /// /// protected virtual ICommand NavigateCommand(string controller, string action, Func canExecute) { var msg = new NavigationMessage(controller, action, MessageToken); return new NavigateCommand(msg, canExecute); } /// /// Creates a new instance of a . /// The defaults to NavigateDirections.Forward. /// This command is disabled if the target controller/action do not exist. /// /// The controller. /// The action. /// protected virtual ICommand NavigateCommand(string controller, string action) { object routeValues = null; return NavigateCommand(controller, action, routeValues); } /// /// Creates a new instance of a . /// This command is disabled if the target controller/action do not exist. /// The defaults to NavigateDirections.Forward. /// /// The controller. /// The action. /// /// The route values passed along the request. /// Expressed as an anonymous type, looks like this: /// new { routeValue1 = "Whatever", routeValue2 = someVariable } /// /// protected virtual ICommand NavigateCommand(string controller, string action, object routeValues) { var direction = NavigationDirections.Forward; return NavigateCommand(controller, action, routeValues, direction); } /// /// Creates a new instance of a . /// This command is disabled if the target controller/action do not exist. /// /// The controller. /// The action. /// /// The route values passed along the request. /// Expressed as an anonymous type, looks like this: /// new { routeValue1 = "Whatever", routeValue2 = someVariable } /// /// /// The direction being navigated. /// This affects the transition used during navigation. /// /// protected virtual ICommand NavigateCommand(string controller, string action, object routeValues, NavigationDirections direction) { return new NavigateCommand(controller, action, routeValues, direction, MessageToken); } /// /// Sends a message indicating the modal window should be closed. /// DialogResult is set to Cancel. /// public void CloseModal() { DialogResult dialogResult = DialogResult.Cancel; object result = null; CloseModal(dialogResult, result); } /// /// Sends a message indicating the modal window should be closed. /// /// The dialog result. /// The result, any data that needs to be sent back to whatever opened the modal. protected void CloseModal(DialogResult dialogResult, object result) { Messenger.Send(new CloseModalMessage(dialogResult, result)); } public ICommand ModalCommand(string controller, string action, Action> processModalResult) { Func canExecute = null; object routeValues = null; return ModalCommand(controller, action, routeValues, canExecute, processModalResult); } public ICommand ModalCommand(string controller, string action, object routeValues, Func canExecute, Action> processModalResult) { return new ModalWindowCommand(controller, action, canExecute, routeValues, processModalResult); } /// /// A command which sends out a request message to open a modal window. /// /// /// The type of data returned by the modal window. /// This also doubles as the type for the CommandParameter. /// /// The controller. /// The action. /// /// The method used to create route values to be passed along a request. /// The method is passed an instance of type TCommandParameter. /// The method should return an anonymous type in a dictionary format(i.e. name/value pairs). /// /// /// Method used to process the results passed back from the modal window. /// /// public ICommand ModalCommand(string controller, string action, Func routeValuesFinder, Action> processModalResult) { Predicate canExecute = null; return ModalCommand(controller, action, routeValuesFinder, canExecute, processModalResult); } /// /// A command which sends out a request message to open a modal window. /// /// /// The type of data returned by the modal window. /// This also doubles as the type for the CommandParameter. /// /// The controller. /// The action. /// /// The method used to create route values to be passed along a request. /// The method is passed an instance of type TCommandParameter. /// The method should return an anonymous type in a dictionary format(i.e. name/value pairs). /// /// /// Defines the method that determines whether the command can execute in its current state. /// This method is passed data of type TModalResult and can be used by the command. /// /// /// Method used to process the results passed back from the modal window. /// /// public ICommand ModalCommand(string controller, string action, Func routeValuesFinder, Predicate canExecute, Action> processModalResult) { return new ModalWindowCommand(controller, action, routeValuesFinder, canExecute, processModalResult); } /// /// A command which sends out a request message to open a modal window. /// /// The type of the command parameter. /// The type of the modal result. /// The controller. /// The action. /// /// The method used to create route values to be passed along a request. /// The method is passed an instance of type TCommandParameter. /// The method should return an anonymous type in a dictionary format(i.e. name/value pairs). /// /// The method used to indicate whether the command can be executed. /// /// The method used to process whatever is returned from the modal window. /// /// public ICommand ModalCommand(string controller, string action, Func routeValuesBuilder, Predicate canExecute, Action> processModalResult) { return new ModalWindowCommand(controller, action, routeValuesBuilder, canExecute, processModalResult); } public ICommand ModalCommand(string controller, string action) { object routeValues = null; Action processModalResult = null; return ModalCommand(controller, action, routeValues, processModalResult); } public ICommand ModalCommand(string controller, string action, object routeValues, Action processModalResult) { return new RelayCommand( () => Messenger.Send(new ModalMessage(controller, action, routeValues, processModalResult)) ); } //protected virtual ILogger Logger //{ // get // { // return LoggerService.GetLogger("Main"); // } //} #region ISupportMessageTokens private string _messageToken; public string MessageToken { get { if (String.IsNullOrEmpty(_messageToken)) { throw new InvalidOperationException("MessageToken is null. MessageToken must be set using SetMessageToken"); } return _messageToken; } } public void SetMessageToken(string messageToken) { if (String.IsNullOrEmpty(messageToken)) throw new ArgumentException("messageToken is null or empty.", "messageToken"); _messageToken = messageToken; } #endregion /// /// Initializes this instance. /// Subclassers can override this method to provide anything that needs to be done when this ViewModel is loaded in a . /// This method does nothing by default. /// Made this public to aid in testing. /// public virtual void Initialize() { } #region IViewAware /// /// Notifies the target that the view has been loaded. /// Explicitly implemented so the interface to the ViewModel doesn't get cluttered. /// Used only by infrastructure. /// void mag.IViewAware.Loaded() { //do nothing for now } /// /// Notifies the target that a view has been attached. /// Explicitly implemented so the interface to the ViewModel doesn't get cluttered. /// Used only by infrastructure. /// /// The view. void mag.IViewAware.ViewAttached(object view) { lock (this) { if (_initialized) return; _initialized = true; Initialize(); } } private bool _initialized = false; #endregion } }