Wpf CommandManager.InvalidateRequestSuggested不会在MVVM指示灯下对CanExecute进行重新查询
我正在使用MVVM Light RelayCommandWpf CommandManager.InvalidateRequestSuggested不会在MVVM指示灯下对CanExecute进行重新查询,wpf,mvvm-light,Wpf,Mvvm Light,我正在使用MVVM Light RelayCommand private ICommand myRevertCmd; public ICommand Revert { get { if (myRevertCmd == null) { myRevertCmd = new RelayCommand(RevertExecute, CanRevertExecute);
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();
但这不起作用。有人有什么建议吗?有很多建议(,)
我使用了一个简单但不太漂亮的变通方法。我只需在我的
BackgroundWorker
Completed事件中为我的命令调用OnPropertyChanged(“MyICommand”)
。我想你可以在“isRevertEnabled
”INPC(或依赖项属性)set方法中调用“Revert.RaiseCanecuteChanged()
”方法。这将强制执行“CanRevertExecute
”谓词。我会将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;
}
根据乔希·史密斯的文章。问题在于该命令是非路由命令 我对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);
// }
}
为了添加另一个可能的解决方案,在我的例子中,我需要使用
Application.Current.Dispatcher.Invoke
调用UI线程上的CommandManager.invalidateRequestSuggested
,只需调用Revert.raiseCanceTechChanged()代码>@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.
这会产生一个编译错误:“event System.Windows.Input.ICommand.CanExecuteChanged只能出现在+=或-=”的左侧。这可能是一个“不太漂亮的解决方法”,但OnPropertyChanged(命令)正好帮了我一把。谢谢你的主意。如果UI不是“重”的,你可以调用OnPropertyChanged(null)
来更新每个属性,包括命令(这将重新评估CanExecute命令),这就是我需要为UI线程上的提示执行+1的操作。我在后台线程上调用了它,但没有发生任何事情,我可以再次投票支持它。我想知道为什么在MVVMLight中默认情况下不这样做,您是将此代码放在ViewModel中还是放在视图的背景代码中?抱歉,我无法获取如何在UI线程上调用它?我将此调用放置在ViewModel中。Application.Current.Dispatcher.Invoke接受它在UI线程上运行的委托。有关更多信息,请参阅MSDN。目前,在另一个命名空间中有一个RelayCommand
的实现:GalaSoft.MvvmLight.CommandWpf
,它专门解决了这个问题!目前,在另一个名称空间中有一个RelayCommand
的实现:GalaSoft.MvvmLight.CommandWpf
专门解决了这个问题!我尝试了下面所有的答案,没有任何效果。但是使用GalaSoft.MvvmLight.CommandWpf.RelayCommand为我解决了这个问题。谢谢你@heltonbiker