OneComputeWpfClient\Support\ParameterlessRelayCommand.cs
using System;
using System.Windows.Input;
namespace OneComputeWpfClient.Support
{
/// <summary>
/// A command whose sole purpose is to relay its functionality to other
/// objects by invoking delegates.
/// </summary>
/// <example>
/// A sample usage of this class is shown below.
/// <code>
/// private ICommand _saveCommand = null;
///
/// public ICommand SaveCommand => _saveCommand ?? (_saveCommand = new ParameterlessRelayCommand(Save, CanSave));
///
/// Separately, it is necessary to implement the above two specified methods:
/// 1) private void Save()
/// 2) private bool CanSave()
///
/// </code>
/// </example>
public class ParameterlessRelayCommand : ICommand
{
/// <summary>
/// Initializes a new instance of the
/// <see cref="ParameterlessRelayCommand"/> class.
/// </summary>
/// <param name="execute">
/// An action to invoke when the command is executed.
/// </param>
/// <param name="canExecute">
/// An optional predicate to determine if the command can execute. If <c>null</c>,
/// it is assumed that the command can always execute.
/// </param>
public ParameterlessRelayCommand(Action execute, Func<bool> canExecute = null)
{
InnerExecute = execute ?? throw new ArgumentNullException(nameof(execute));
InnerCanExecute = canExecute;
}
/// <summary>
/// Gets the function that determines if the command can execute.
/// </summary>
private Func<bool> InnerCanExecute { get; }
/// <summary>
/// Gets the action to execute.
/// </summary>
private Action InnerExecute { get; }
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">
/// Data used by the command. This parameter is ignored (i.e. not used).
/// </param>
/// <returns>
/// <c>true</c> if this command can be executed; otherwise, <c>false</c>.
/// </returns>
bool ICommand.CanExecute(object parameter) =>
CanExecute();
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <returns>
/// <c>true</c> if this command can be executed; otherwise, <c>false</c>.
/// </returns>
public bool CanExecute() =>
InnerCanExecute?.Invoke() ?? true;
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">
/// Data used by the command. This parameter is ignored (i.e. not used).
/// </param>
void ICommand.Execute(object parameter) =>
Execute();
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
public void Execute() =>
InnerExecute?.Invoke();
/// <summary>
/// Raises the CanExecuteChanged event.
/// </summary>
public void RaiseCanExecuteChanged() =>
CommandManager.InvalidateRequerySuggested();
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
/// <remarks>
/// Delegate event subscription to the CommandManager.RequerySuggested event. This
/// ensures that the WPF commanding infrastructure asks all ParameterlessRelayCommand
/// objects if they can execute whenever it asks the built-in commands.
/// </remarks>
event EventHandler ICommand.CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
}