using System; using System.Diagnostics; using System.Threading; using System.Windows; using System.Windows.Input; using System.Windows.Threading; namespace Kent.Boogaart.MVVM { /// /// A base class for command implementations. /// public abstract class Command : ICommand { private readonly Dispatcher _dispatcher; /// /// Constructs an instance of CommandBase. /// protected Command() { if (Application.Current != null) { _dispatcher = Application.Current.Dispatcher; } else { //this is useful for unit tests where there is no application running _dispatcher = Dispatcher.CurrentDispatcher; } Debug.Assert(_dispatcher != null); } /// /// Occurs whenever the state of the application changes such that the result of a call to may return a different value. /// public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } /// /// Determines whether this command can execute. /// /// /// The command parameter. /// /// /// if the command can execute, otherwise . /// public abstract bool CanExecute(object parameter); /// /// Executes this command. /// /// /// The command parameter. /// public abstract void Execute(object parameter); /// /// Raises the event. /// protected virtual void OnCanExecuteChanged() { if (!_dispatcher.CheckAccess()) { _dispatcher.Invoke((ThreadStart)OnCanExecuteChanged, DispatcherPriority.Normal); } else { CommandManager.InvalidateRequerySuggested(); } } } }