C#ICommand可以执行

时间:2018-07-17 20:31:34

标签: c# wpf interface icommand

我试图了解ICommand接口。我使用按钮创建了一个应用程序,该按钮使用了一个名为RelayCommand的类,该类继承自ICommand。该类如下所示:

    class RelayCommand : ICommand
{
    private Action<object> _action;
    public RelayCommand(Action<object> action)
    {
        _action = action;
    }

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

    public void Execute(object parameter)
    {
        if(parameter != null)
        {
            _action(parameter);
        }
        else
        {
            _action("Hello World");
        }
    }

    //We need to include CanExecuteChange when using the Interface ICommand 
    //In this case it doesn't actually do anything.
    public event EventHandler CanExecuteChanged;

}

每次我跟踪该函数时,我都点击了CanExecute方法,但是现在我在代码中的任何地方都调用了此方法。我这样创建一个RelayCommand实例:

Btn_AcceptedAnswer = new RelayCommand(new Action<object>(AcceptedAnswer_OnClick));

所以我的问题是,当RelayCommand启动时,它如何知道运行CanExecute()和Execute(),以及它们何时运行它们?我知道如何实施事件,只是想了解事件的工作原理。

1 个答案:

答案 0 :(得分:4)

正在调用CanExecute的UI(WPF)知道是否必须启用与该命令关联的按钮。

按下按钮时会调用

Execute

您可以在CanExecuteChanged的条件更改时引发(调用)CanExecute事件,以通知UI重新查询它。例如,命令可以是与绑定到网格视图,组合框等的列表集合有关的“清除”命令。如果列表从空变为非空(反之亦然),请加CanExecuteChanged。当然,仅当列表不为空时,才会启用该按钮。

public bool CanExecute(object parameter)
{
    return myList.Count > 0;
}

private void OnCanExecuteChanged()
{
    CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

public void Execute(object parameter)
{
    if(myList.Count > 0) {
        myList.Clear();
        OnCanExecuteChanged();
    }
}

将元素添加到列表时,您也应该触发事件。但是,这很棘手,因为这很可能在另一个命令中发生。您将需要一种在两者之间进行通信的方法。一个不错的选择是使用ObservableCollection<T>BindingList<T>。列表更改时,两者都会引发事件(请参阅:Difference between ObservableCollection and BindingList)。然后,这些命令可以订阅绑定列表事件。 BindingList<T>的另一个效果是它绑定到的UI元素会在列表更改时自动更新。