// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Command.cs" company="Catel development team">
// Copyright (c) 2008 - 2011 Catel development team. All rights reserved.
// </copyright>
// <summary>
// Class to implement commands in the <see cref="ViewModelBase" />.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Windows.Input;
namespace Catel.MVVM
{
/// <summary>
/// Class to implement commands in the <see cref="ViewModelBase"/>.
/// </summary>
/// <typeparam name="TExecuteParameter">The type of the execute parameter.</typeparam>
/// <typeparam name="TCanExecuteParameter">The type of the can execute parameter.</typeparam>
/// <remarks>
/// This is partly based on the Command as implemented in Cinch. Cinch is another open-source MVVM-framework
/// (see http://cinch.codeplex.com), which (probably) based the command on http://marlongrech.wordpress.com/2008/11/26/avoiding-commandbinding-in-the-xaml-code-behind-files/.
/// </remarks>
public class Command<TExecuteParameter, TCanExecuteParameter> : ICommand, ICatelCommand
{
#region Variables
private readonly Func<TCanExecuteParameter, bool> _canExecute;
private readonly Action<TExecuteParameter> _execute;
#endregion
#region Constructor & destructor
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="execute">The action to execute.</param>
public Command(Action<TExecuteParameter> execute)
: this(execute, null) { }
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="canExecute">The function to call to determine wether the command can be executed.</param>
/// <param name="execute">The action to execute.</param>
public Command(Action<TExecuteParameter> execute, Func<TCanExecuteParameter, bool> canExecute)
{
_canExecute = canExecute;
_execute = execute;
}
#endregion
#region Events
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
#if SILVERLIGHT
public event EventHandler CanExecuteChanged;
#else
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
{
CommandManager.RequerySuggested += value;
}
}
remove
{
if (_canExecute != null)
{
CommandManager.RequerySuggested -= value;
}
}
}
#endif
#endregion
#region Properties
#endregion
#region Methods
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
public bool CanExecute(object parameter)
{
return CanExecute((TCanExecuteParameter)parameter);
}
/// <summary>
/// Determines whether this instance can execute the specified parameter.
/// </summary>
/// <param name="parameter">The parameter.</param>
/// <returns>
/// <c>true</c> if this instance can execute the specified parameter; otherwise, <c>false</c>.
/// </returns>
public bool CanExecute(TCanExecuteParameter parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public void Execute(object parameter)
{
Execute((TExecuteParameter)parameter);
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public void Execute(TExecuteParameter parameter)
{
if (_execute != null)
{
_execute(parameter);
}
}
/// <summary>
/// Raises the <see cref="CanExecuteChanged"/> event.
/// </summary>
public void RaiseCanExecuteChanged()
{
#if SILVERLIGHT
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
#else
CommandManager.InvalidateRequerySuggested();
#endif
}
#endregion
}
/// <summary>
/// Implements the <see cref="Command{TExecuteParameter, TCanExecuteParameter}"/> class with only the <typeparamref name="TExecuteParameter"/> as generic type.
/// </summary>
/// <typeparam name="TExecuteParameter">The type of the execute parameter.</typeparam>
public class Command<TExecuteParameter> : Command<TExecuteParameter, object>
{
#region Constructor & destructor
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="execute">The action to execute.</param>
public Command(Action<TExecuteParameter> execute)
: this(execute, null) { }
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="canExecute">The function to call to determine wether the command can be executed.</param>
/// <param name="execute">The action to execute.</param>
public Command(Action<TExecuteParameter> execute, Func<object, bool> canExecute)
: base(execute, canExecute) { }
#endregion
}
/// <summary>
/// Implements the <see cref="Command{TExecuteParameter, TCanExecuteParameter}"/> class with <see cref="Object"/> as generic types.
/// </summary>
public class Command : Command<object, object>
{
#region Constructor & destructor
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="execute">The action to execute.</param>
public Command(Action<object> execute)
: this(execute, null) { }
/// <summary>
/// Initializes a new instance of the <see cref="Command{TCanExecuteParameter,TExecuteParameter}"/> class.
/// </summary>
/// <param name="canExecute">The function to call to determine wether the command can be executed.</param>
/// <param name="execute">The action to execute.</param>
public Command(Action<object> execute, Func<object, bool> canExecute)
: base(execute, canExecute) { }
#endregion
}
}