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

C# ICommand-RelayCommand CanExecute方法不更新按钮IsEnabled属性,c#,wpf,binding,icommand,relaycommand,C#,Wpf,Binding,Icommand,Relaycommand,我的viewModel中有以下RelayCommand实现: RelayCommand _resetCounter; private void ResetCounterExecute() { _data.ResetCounter(); } private bool CanResetCounterExecute() { if (_data.Counter > 0) { return true; } else {

我的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; 
    }
}
通过调用
\u data.ResetCounter()在ResetCounterExecute方法中,我在模型中将计数器值重置为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();
    }
}
内部类RelayCommand:ICommand
{
只读操作_执行;
只读功能可执行;
公共中继命令(操作执行)
:此(执行,空)
{
}
公共RelayCommand(操作执行,函数执行)
{
if(execute==null)
抛出新的ArgumentNullException(“执行”);
_执行=执行;
_canExecute=canExecute;
}
[调试步骤至]
公共布尔CanExecute(对象参数)
{
return _canExecute==null?true:_canExecute();
}
公共事件事件处理程序CanExecuteChanged
{
添加
{
如果(_canExecute!=null)
CommandManager.RequerySuggested+=值;
}
去除
{
如果(_canExecute!=null)
CommandManager.RequerySuggested-=值;
}
}
public void Execute(对象参数)
{
_执行();
}
}
在XAML中,我将comman绑定到一个按钮:

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

我的问题是,只要单击UI中的任何控件,按钮就会被启用。但我需要的是,一旦我的
\u data.Counter>0
应用,按钮就会被启用。因此,根据我的研究,我似乎需要实现
CommandManager.invalidateRequestSuggested()
或使用
RelayCommand.raiseCancecutechanged()

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

另外,我想问一下,在我目前的情况下,我必须如何实现
RelayCommand.raisecannexecutechanged()
。如果给定条件,我应该在何处以及如何提升它以确保UI更改按钮状态


提前感谢。

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

或者您也可以实施
RaiseCanceTechChanged
。这可能是触发相同事件的更可靠方法

范例

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

此外,您可能还想阅读

@pushraj:谢谢您的提示。但是我不明白如何将
RaiseCanceTechChanged
实现到我的代码中。如何以及在何处添加嵌套类?您可以简单地用答案中的代码替换代码中的
CanExecuteChanged
,它不是嵌套类,而是您的类带有。。。表示公共代码。不知道为什么我没有得到它。非常感谢。它现在工作得很好!