Search code examples
c#uwprelaycommanduno

UWP: Int parameter fails on RelayCommand


This code with string parameter work:

public RelayCommand<string> myCommand { get; private set; }
myCommand = new RelayCommand<string>((s) => Test(s));

private void Test(string s)
{
    //DoSomething();
}

This code with int parameter does not work and gives Compiler Error CS0452:

public RelayCommand<int> myCommand { get; private set; }
myCommand = new RelayCommand<int>((s) => Test(s));

private void Test(int s)
{
    //DoSomething();
}

RelayCommand Class to bind with command on xaml UI:

    public class RelayCommand<TParameter> : System.Windows.Input.ICommand
where TParameter : class
{
    protected readonly System.Func<TParameter, bool> _canExecute;
    private readonly System.Action<TParameter> _execute;
    public RelayCommand(System.Action<TParameter> execute)
    : this(execute, null)
    {
    }
    public RelayCommand(System.Action<TParameter> execute, System.Func<TParameter, bool> canExecute)
    {
        if (execute == null)
        { 
            throw new ArgumentNullException("execute");
        }
            
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter as TParameter);
    }
    public void Execute(object parameter)
    {
        _execute(parameter as TParameter);
    }
    public event EventHandler CanExecuteChanged;
    public void RaiseCanExecuteChanged()
    {
        System.EventHandler handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, System.EventArgs.Empty);
        }
    }
}

Any ideas other than convert it to object type?


Solution

  • If you want to be able to use your RelayCommand<TParameter> implementation with a value type such as int, you need to remove the type constraint and the use of the as operator:

    public class RelayCommand<TParameter> : System.Windows.Input.ICommand
    {
        protected readonly System.Func<TParameter, bool> _canExecute;
        private readonly System.Action<TParameter> _execute;
        public RelayCommand(System.Action<TParameter> execute)
        : this(execute, null)
        {
        }
        public RelayCommand(System.Action<TParameter> execute, System.Func<TParameter, bool> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }
    
            _execute = execute;
            _canExecute = canExecute;
        }
    
        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
                return true;
    
            if (parameter is TParameter)
                return _canExecute((TParameter)parameter);
    
            return false;
        }
        public void Execute(object parameter)
        {
            if (parameter is TParameter)
                _execute((TParameter)parameter);
        }
        public event EventHandler CanExecuteChanged;
        public void RaiseCanExecuteChanged()
        {
            System.EventHandler handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, System.EventArgs.Empty);
            }
        }
    }