2
votes

I Have Implemented Icommand in my mvvm architecture as SimpleCommand.cs

 public class SimpleCommand<T1, T2> : ICommand
{
    private Func<T1, bool> canExecuteMethod;
    private Action<T2> executeMethod;

    public SimpleCommand(Func<T1, bool> canExecuteMethod, Action<T2> executeMethod)
    {
        this.executeMethod = executeMethod;
        this.canExecuteMethod = canExecuteMethod;
    }

    public SimpleCommand(Action<T2> executeMethod)
    {
        this.executeMethod = executeMethod;
        this.canExecuteMethod = (x) => { return true; };
    }

    public bool CanExecute(T1 parameter)
    {
        if (canExecuteMethod == null) return true;
        return canExecuteMethod(parameter);
    }

    public void Execute(T2 parameter)
    {
        if (executeMethod != null)
        {
            executeMethod(parameter);
        }
    }

    public bool CanExecute(object parameter)
    {
        return CanExecute((T1)parameter);
    }

    public void Execute(object parameter)
    {
        Execute((T2)parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged()
    {
        var handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

And Implemented this ICommand in my viewModel As follows:

private ICommand printCommand;

    public ICommand PrintCommand
    {
        get { return printCommand; }
        set { printCommand = value; }
    }




myviewmodel() // in Constructor of ViewModel
 {

   this.PrintCommand = new SimpleCommand<Object, EventToCommandArgs>(ExecutePrintCommand);
}

 }

On XAML : I Have Called Command="{Binding PrintCommand}"

<Button Content="Print Button" Command="{Binding PrintCommand}" Width="120" Height="25" Margin="3"></Button>

It Works Perfectly...

But When I try To Send CommandParameter to Command As:

<Button Content="Print Button" Command="{Binding PrintCommand}" Width="120" Height="25" Margin="3" CommandParameter="{Binding ElementName=grdReceipt}"></Button>

Then Command is not executing. and Giving Error as :

Unable to cast object of type 'System.Windows.Controls.Grid' to type 'PropMgmt.Shared.EventToCommandArgs'.

Please Help.Thanks In Advance.

1

1 Answers

2
votes

The problem is this part in your SimpleCommand implementation

public void Execute(object parameter){
  Execute((T2)parameter);
}

T2 in your case is of type EventToCommandArgs, but as parameter

CommandParameter="{Binding ElementName=grdReceipt}"

you are passing a System.Windows.Controls.Grid, which results in the exception you have mentioned.

Also is your implementation of the command incorrect. The parameter passed to CanExecute and Execute are the same object. The following implementation works using only one generic type.

public class SimpleCommand<T1> : ICommand
{
    private Func<T1, bool> canExecuteMethod;
    private Action<T1> executeMethod;

    public SimpleCommand(Func<T1, bool> canExecuteMethod, Action<T1> executeMethod)
    {
        this.executeMethod = executeMethod;
        this.canExecuteMethod = canExecuteMethod;
    }

    public SimpleCommand(Action<T1> executeMethod)
    {
        this.executeMethod = executeMethod;
        this.canExecuteMethod = (x) => { return true; };
    }

    public bool CanExecute(T1 parameter)
    {
        if (canExecuteMethod == null) return true;
        return canExecuteMethod(parameter);
    }

    public void Execute(T1 parameter)
    {
        if (executeMethod != null)
        {
            executeMethod(parameter);
        }
    }

    public bool CanExecute(object parameter)
    {
        return CanExecute((T1)parameter);
    }

    public void Execute(object parameter)
    {
        Execute((T1)parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged()
    {
        var handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

Using this implementation you can define:

this.PrintCommand = new SimpleCommand<object>(ExecutePrintCommand);

Since your ExecutePrintCommand gets an object as parameter you need to do a type check or cast to the type you need. In your case you will get a System.Windows.Controls.Grid.

public void ExecutPrintCommand(object parameter) {
    System.Windows.Controls.Grid grid = parameter as System.Windows.Controls.Grid;

    if (grid != null) {
      // do something with the Grid
    }
    else {
      // throw exception or cast to another type you need if your command should support more types.
    }
  }