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();
}
}
}
}