将Command CanExecute和Executed处理程序放在主窗口类之外的问题

时间:2011-11-13 16:26:20

标签: c# wpf command commandbinding

基本上我已经为分配给Window.CommandBindings的命令本身提供了命令绑定:

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

local是默认生成的命名空间,指向应用程序的命名空间。我在这里想要实现的是在TimerViewModel中进行命令处理但是我一直收到以下错误:

  

CanExecute =“local:TimerViewModel.AddTimer_CanExecute”无效。 'local:TimerViewModel.AddTimer_CanExecute'不是有效的事件处理程序方法名称。只有生成的或代码隐藏类的实例方法才有效。

虽然TimerViewModel非常简单,但我相信我错过了一些东西:

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())));
    }
}

有人能指出我正在犯的错误吗?

2 个答案:

答案 0 :(得分:2)

查看http://www.wpftutorial.net/DelegateCommand.html以获取如何为WPF实现委托命令的示例。它允许您将Execute和CanExecute连接为事件处理程序。如果您直接使用RoutedUICommand,则需要从中派生自定义命令并使用您的函数覆盖Execute和CanExecute。

答案 1 :(得分:2)

另请参阅Josh Smith的RelayCommand。使用它可以让你像这样写上面的内容:

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())));
    }
}