C# ICommand Can Execute

4

我想要理解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个回答

6

这是 UI(WPF)调用 CanExecute 来确定与命令相关联的按钮是否必须启用。

Execute 在按下按钮时被调用。

CanExecute 的条件改变时,您可以触发(调用)CanExecuteChanged 事件,通知 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>。两者在列表更改时都会引发事件(请参阅:ObservableCollection和BindingList之间的区别)。然后,命令可以订阅绑定列表事件。 BindingList<T>的附加效果是它绑定的UI元素会在列表更改时自动更新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接