CommandManager.InvalidateRequerySuggested不会导致MVVM-Light中的CanExecute重新查询

时间:2011-05-17 09:04:40

标签: wpf mvvm-light

我正在使用MVVM-Light RelayCommand

private ICommand myRevertCmd;
public ICommand Revert
    {
        get
        {
            if (myRevertCmd == null)
            {
                myRevertCmd = new RelayCommand(RevertExecute, CanRevertExecute);
            }

            return myRevertCmd;
        }
    }

    private void RevertExecute()
    {
        searchType = SearchType.Revert;
        SearchStart();
    }

    private bool CanRevertExecute()
    {
        return isRevertEnabled;
    }

我有一些代码可以更改isRevertEnabled的值,但链接的按钮不会更改。经过一些搜索后,我发现你可以用来强制重新评估按钮状态

// force the GUI to re-evaluate the state of the buttons
CommandManager.InvalidateRequerySuggested();

但这不起作用。有没有人有任何建议?

7 个答案:

答案 0 :(得分:28)

只是为了添加另一个可能的解决方案,在我的情况下,我需要使用CommandManager.InvalidateRequerySuggested在UI线程上调用Application.Current.Dispatcher.Invoke

答案 1 :(得分:7)

有很多建议(hereherehere)。

我使用简单但不那么漂亮的解决方法。我只需在OnPropertyChanged("MyICommand")已完成的事件中为我的命令调用BackgroundWorker

答案 2 :(得分:4)

根据Josh Smith的文章'Allowing CommandManager to query your ICommand objects'。问题是该命令是非路由命令。

我已经按照以下方式对MVVM-Light RelayCommand进行了新的实现:

// original
//public event EventHandler CanExecuteChanged;


public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

public void RaiseCanExecuteChanged()
{
    CommandManager.InvalidateRequerySuggested();
    //            var handler = CanExecuteChanged;
    //            if (handler != null)
    //            {
    //                handler(this, EventArgs.Empty);
    //            }
}

答案 3 :(得分:0)

我猜你可以在“Revert.RaiseCanExecuteChanged()”INPC(或依赖属性)set方法中调用“isRevertEnabled”方法。这将强制使用“CanRevertExecute”谓词。

答案 4 :(得分:0)

我会将isRevertEnabled标志转换为属性并从那里调用OnPropertyChanged方法(您需要实现INotifyPropertyChanged接口)。在您更改标志的位置,您需要使用该属性,例如IsRevertEnabled = true。

private bool isRevertEnabled;

public bool IsRevertEnabled
{
    get
    {
        return isRevertEnabled;
    }
    set
    {
        if (isRevertEnabled != value)
        {
            isRevertEnabled = value;
            OnPropertyChanged("IsRevertEnabled");
        }
    }
}

private bool CanRevertExecute()     
{         
    return IsRevertEnabled;     
}

答案 5 :(得分:0)

只需致电Revert.RaiseCanExecuteChanged();

答案 6 :(得分:0)

@heltonbiker 已经在评论中指出了这一点,但解决方案是更改命名空间。

如果您查看 RelayCommand 的源代码,您会看到以下注释:

// Remarks:
//     If you are using this class in WPF4.5 or above, you need to use the GalaSoft.MvvmLight.CommandWpf
//     namespace (instead of GalaSoft.MvvmLight.Command). This will enable (or restore)
//     the CommandManager class which handles automatic enabling/disabling of controls
//     based on the CanExecute delegate.