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

发布于 2024-11-07 13:00:31 字数 757 浏览 0 评论 0原文

我正在使用 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();

但这不起作用。有人有什么建议吗?

I am using 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;
    }

I have some code that changes the value of isRevertEnabled but the linked button does not change. After some searching I found that you can use to force the re-evaluation of the button states

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

But this doesn't work. Does any one have any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

白日梦 2024-11-14 13:00:31

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

Just to add another possible solution, in my case I needed to call CommandManager.InvalidateRequerySuggested on the UI thread using Application.Current.Dispatcher.Invoke.

ゞ记忆︶ㄣ 2024-11-14 13:00:31

有很多建议(此处此处此处)。

我使用一个简单但不太漂亮的解决方法。我只需在 BackgroundWorker Completed 事件中调用 OnPropertyChanged("MyICommand") 来获取命令。

There are a lot suggestions out there (here, here, here).

I use a simple but not so beautiful workaround. I simply call OnPropertyChanged("MyICommand") for my commands in my BackgroundWorker Completed Event.

半世蒼涼 2024-11-14 13:00:31

根据 Josh Smith 的文章 '允许 CommandManager查询您的 ICommand 对象'。问题在于该命令是非路由命令。

我对 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);
    //            }
}

According to Josh Smith's article 'Allowing CommandManager to query your ICommand objects'. The problem is that the command is a non-routed command.

I have made a new implementation of the MVVM-Light RelayCommand as follows:

// 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);
    //            }
}
岁吢 2024-11-14 13:00:31

我会将 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;     
}

I would turn the isRevertEnabled flag into a property and call the OnPropertyChanged method from there (you need to implement the INotifyPropertyChanged interface). At the point where you change the flag, you need to use the property, e.g. IsRevertEnabled = true.

private bool isRevertEnabled;

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

private bool CanRevertExecute()     
{         
    return IsRevertEnabled;     
}
在梵高的星空下 2024-11-14 13:00:31

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

I guess you can call "Revert.RaiseCanExecuteChanged()" method at "isRevertEnabled" INPC (or dependency property) set method. This will force the "CanRevertExecute" predicate.

一张白纸 2024-11-14 13:00:31

只需调用 Revert.RaiseCanExecuteChanged();

Just call Revert.RaiseCanExecuteChanged();

送你一个梦 2024-11-14 13:00:31

@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.

@heltonbiker already pointed this out in comments, but the solution is to change namespaces.

If you look at the source for RelayCommand, you see the following remark:

// 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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文