ICommand - RelayCommand CanExecute方法不更新按钮IsEnabled属性

时间:2014-09-18 04:38:35

标签: c# wpf binding icommand relaycommand

我在viewModel中有以下RelayCommand实现:

RelayCommand _resetCounter;

private void ResetCounterExecute()
{
    _data.ResetCounter();
}

private bool CanResetCounterExecute()
{
    if (_data.Counter > 0)
    {
        return true;
    }
    else
    {
        return false;
    }

}

public ICommand ResetCounter
{ 
    get 
    {

        if (_resetCounter == null)
        {
            _resetCounter = new RelayCommand(this.ResetCounterExecute,this.CanResetCounterExecute);
        }
        return _resetCounter; 
    }
}

通过在ResetCounterExecute方法中调用_data.ResetCounter();,我将模型中的计数器值重置为0.

这是我根据样本使用的RealyCommand类的实现。

internal class RelayCommand : ICommand
{
    readonly Action _execute;
    readonly Func<bool> _canExecute;

    public RelayCommand(Action execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action execute, Func<bool> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute();
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }
        remove
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }

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

在XAML中,我将comman绑定到一个按钮:

<Button Name="btnResetCount" Content="Reset" Command="{Binding Path=CounterViewModel.ResetCounter}" Click="btnResetCount_Click">

我的问题是,当我点击UI中的任何控件时,该按钮才会启用。但我需要的是,一旦_data.Counter > 0适用,该按钮就会启用。因此,根据我的研究,我似乎需要实施CommandManager.InvalidateRequerySuggested();或使用RelayCommand.RaiseCanExecuteChanged()

我想知道这两种方式是否是通知UI刷新绑定的唯一方法。

此外,我想问一下如何在我目前的案例中实施RelayCommand.RaiseCanExecuteChanged()。我应该在哪里以及如何提高它以确保在给定条件时UI改变按钮状态。

提前致谢。

1 个答案:

答案 0 :(得分:1)

使用CommandManager.RequerySuggested时,您可以通过调用RequerySuggested

强制CommandManager调用CommandManager.InvalidateRequerySuggested()事件

或者您也许可以实施RaiseCanExecuteChanged。这可能是更可靠的触发方法。

例如

internal class RelayCommand : ICommand
{
    ...

    public event EventHandler CanExecuteChanged;

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

    ...
}

当您想要无效或_data.Counter更改时,请调用

ResetCounter.RaiseCanExecuteChanged();

另外,您可能还想阅读How does CommandManager.RequerySuggested work?