/// <summary>
/// Executes the <see cref="RelayCommand"/> on the current command target.
/// </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.
/// this object can be set to null.
/// </param>
public void Execute(object parameter)
{
_execute();
}
this method doesn't actually call the Action delegate "_execute()" with the Parameter, so why the hell is it there? seriously if someone knows please tell me.
What I did to get around this kerfuffle, is I added a private Action<object> delegate to store my command that expects a parameter.
private readonly Action<object> _executeWithParameter;
I then added added two constructors one that would accept my Action<object> delegate and a second that would accept both my Action<object> delegate and a func<bool> delegate for canExecute, much like the logic that is auto generated for you.
/// <summary>
/// Creates a new command that expects a parameter
/// </summary>
/// <param name="execute"></param>
public RelayCommand(Action<object> execute) : this(execute, null) { }
/// <summary>
/// Creates a new command that expects a parameter
/// </summary>
/// <param name="execute"></param>
/// <param name="canExecute"></param>
public RelayCommand(Action<object> execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_executeWithParameter = execute;
_canExecute = canExecute;
}
now finally I modified the Execute Method to call the parameter-less _execute delegate if either the parameter or my _executeWithParameter delegate is null, otherwise I call my _executeWithParameter Delegate.
/// <summary>
/// Executes the <see cref="RelayCommand"/> on the current command target.
/// </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)
{
if (parameter == null || _executeWithParameter == null)
_execute();
else
_executeWithParameter(parameter);
}
Now I'm not 100% sure if this is the best way to skin this cat, but it's what I did and it's working, if someone has a better solution that doesn't involve installing a mvvm toolkit, I'm all ears.
The Final class looks like the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace pc.activFitnes.phone81.Common
{
/// <summary>
/// A command whose sole purpose is to relay its functionality
/// to other objects by invoking delegates.
/// The default return value for the CanExecute method is 'true'.
/// <see cref="RaiseCanExecuteChanged"/> needs to be called whenever
/// <see cref="CanExecute"/> is expected to return a different value.
/// </summary>
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Action<object> _executeWithParameter;
private readonly Func<bool> _canExecute;
/// <summary>
/// Raised when RaiseCanExecuteChanged is called.
/// </summary>
public event EventHandler CanExecuteChanged;
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action execute) : this(execute, null) { }
/// <summary>
/// Creates a new command that expects a parameter
/// </summary>
/// <param name="execute"></param>
public RelayCommand(Action<object> execute) : this(execute, null) { }
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
/// <summary>
/// Creates a new command that expects a parameter
/// </summary>
/// <param name="execute"></param>
/// <param name="canExecute"></param>
public RelayCommand(Action<object> execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_executeWithParameter = execute;
_canExecute = canExecute;
}
/// <summary>
/// Determines whether this <see cref="RelayCommand"/> 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 == null ? true : _canExecute();
}
/// <summary>
/// Executes the <see cref="RelayCommand"/> on the current command target.
/// </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)
{
if (parameter == null || _executeWithParameter == null)
_execute();
else
_executeWithParameter(parameter);
}
/// <summary>
/// Method used to raise the <see cref="CanExecuteChanged"/> event
/// to indicate that the return value of the <see cref="CanExecute"/>
/// method has changed.
/// </summary>
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}