Johnny
Johnny

Reputation: 879

Issue with putting Command CanExecute and Executed handlers out of the main window class

Basically I've got a command binding for the command itself assigned to Window.CommandBindings:

<CommandBinding Command="local:TimerViewModel.AddTimer" 
    CanExecute="local:TimerViewModel.AddTimer_CanExecute" 
    Executed="local:TimerViewModel.AddTimer_Executed" />

local is a namespace generated by default pointing to the namespace of the application. What I'm trying to achieve here is to have the command handling inside the TimerViewModel but I keep getting the following error:

CanExecute="local:TimerViewModel.AddTimer_CanExecute" is not valid. 'local:TimerViewModel.AddTimer_CanExecute' is not a valid event handler method name. Only instance methods on the generated or code-behind class are valid.

The TimerViewModel is pretty simple though but I believe I am missing something:

public class TimerViewModel : ViewModelBase
{
    public TimerViewModel()
    {
        _timers = new ObservableCollection<TimerModel>();
        _addTimer = new RoutedUICommand("Add Timer", "AddTimer", GetType());
    }

    private ObservableCollection<TimerModel> _timers;

    public ObservableCollection<TimerModel> Timers
    {
        get { return _timers; }
    }

    private static RoutedUICommand _addTimer;

    public static RoutedUICommand AddTimer
    {
        get { return _addTimer; }
    }

    public void AddTimer_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    public void AddTimer_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        _timers.Add(new TimerModel(TimeSpan.FromSeconds((new Random()).Next())));
    }
}

Can anyone point out the mistakes I'm making?

Upvotes: 2

Views: 496

Answers (2)

ssarabando
ssarabando

Reputation: 3517

Also take a look at Josh Smith's RelayCommand. Using it would enable you to write the above like this:

public class TimerViewModel : ViewModelBase {
    public TimerViewModel() {
        Timers = new ObservableCollection<TimerModel>();
        AddTimerCommand = new RelayCommand(() => AddTimer());
    }

    public ObservableCollection<TimerModel> Timers {
        get;
        private set;
    }

    public ICommand AddTimerCommand {
        get;
        private set;
    }

    private void AddTimer() {
        Timers.Add(new TimerModel(TimeSpan.FromSeconds((new Random()).Next())));
    }
}

Upvotes: 2

Wayne Tanner
Wayne Tanner

Reputation: 1356

Take a look at http://www.wpftutorial.net/DelegateCommand.html for an example of how to implement the delegate command for WPF. It allows you to hook up Execute and CanExecute as event handlers. If you're using RoutedUICommand directly you need to derive a custom command from it and override Execute and CanExecute with your functions.

Upvotes: 2

Related Questions