using System; using System.Linq.Expressions; using System.Reflection; using System.Windows.Input; namespace WxOrder.Framework.Commons { public class DelegateCommand : DelegateCommandBase { readonly Action _executeMethod; Func _canExecuteMethod; /// /// Initializes a new instance of . /// /// Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate. /// will always return true. public DelegateCommand(Action executeMethod) : this(executeMethod, (o) => true) { } /// /// Initializes a new instance of . /// /// Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate. /// Delegate to execute when CanExecute is called on the command. This can be null. /// When both and are . public DelegateCommand(Action executeMethod, Func canExecuteMethod) : base() { if (executeMethod == null || canExecuteMethod == null) throw new ArgumentNullException(nameof(executeMethod), "Delegate Command Delegates Cannot Be Null"); TypeInfo genericTypeInfo = typeof(T).GetTypeInfo(); // DelegateCommand allows object or Nullable<>. // note: Nullable<> is a struct so we cannot use a class constraint. if (genericTypeInfo.IsValueType) { if (!genericTypeInfo.IsGenericType || !typeof(Nullable<>).GetTypeInfo().IsAssignableFrom(genericTypeInfo.GetGenericTypeDefinition().GetTypeInfo())) { throw new InvalidCastException("Delegate CommandInvalid Generic Payload Type"); } } _executeMethod = executeMethod; _canExecuteMethod = canExecuteMethod; } /// ///Executes the command and invokes the provided during construction. /// ///Data used by the command. public void Execute(T parameter) { _executeMethod(parameter); } /// ///Determines if the command can execute by invoked the provided during construction. /// ///Data used by the command to determine if it can execute. /// /// if this command can be executed; otherwise, . /// public bool CanExecute(T parameter) { return _canExecuteMethod(parameter); } /// /// Handle the internal invocation of /// /// Command Parameter protected override void Execute(object parameter) { Execute((T)parameter); } /// /// Handle the internal invocation of /// /// /// if the Command Can Execute, otherwise protected override bool CanExecute(object parameter) { return CanExecute((T)parameter); } /// /// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications. /// /// The type of the return value of the method that this delegate encapsulates /// The property expression. Example: ObservesProperty(() => PropertyName). /// The current instance of DelegateCommand public DelegateCommand ObservesProperty(Expression> propertyExpression) { ObservesPropertyInternal(propertyExpression); return this; } /// /// Observes a property that is used to determine if this command can execute, and if it implements INotifyPropertyChanged it will automatically call DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications. /// /// The property expression. Example: ObservesCanExecute(() => PropertyName). /// The current instance of DelegateCommand public DelegateCommand ObservesCanExecute(Expression> canExecuteExpression) { Expression> expression = Expression.Lambda>(canExecuteExpression.Body, Expression.Parameter(typeof(T), "o")); _canExecuteMethod = expression.Compile(); ObservesPropertyInternal(canExecuteExpression); return this; } } }