我使用两个绑定到用RelayCommands委托初始化的CanExecute的按钮。
RelayCommand DeleteCommand;
bool CanDelete()
{
return BoolProp1 && BoolProp2;
}
...
DeleteCommand = new RelayCommand(Delete, CanDelete);BoolProp1和BoolProp2是常规属性,setter正确地提高了PropertyChanged,但我们都知道,这不足以使SL重新评估命令上的CanExecute。这就是为什么我在两个设置器中都调用Delete.RaiseCanExecuteChanged()的原因。
所有这些都可以正常工作(按钮被禁用并正确启用),直到某个时候,所有的停止都在那里。此时,调用Delete.RaiseCanExecuteChanged()不再触发CanDelete()中的断点,按钮永远保持原样。
我花了2个小时试图找出确切的原因,但没有效果。我怀疑在单个“绑定迭代”期间,多个RaiseCanExecuteChanged()调用以某种方式破坏了这种机制。
有什么暗示吗?我已经在考虑使用通过IsExecutable刷新的额外的INotifyPropertyChanged字段.
更新
RelayCommand实际上是来自MVVM轻型工具包的GalaSoft.MvvmLight.Command.RelayCommand。ILSpy展示了一个非常简单的ICommand实现:
public bool CanExecute(object parameter)
{
return this._canExecute == null || this._canExecute.Invoke();
}
public void RaiseCanExecuteChanged()
{
EventHandler canExecuteChanged = this.CanExecuteChanged;
if (canExecuteChanged != null)
{
canExecuteChanged.Invoke(this, EventArgs.Empty);
}
}将_canExecute设为Func<bool>,将其设置为传递给构造函数的值一次。
我仍在尽量少地重复这个问题。
更新
看看我的答案。
发布于 2011-08-03 22:01:32
PEBKAC。我的框架在某些情况下运行代码
DeleteCommand = new RelayCommand(Delete, CanDelete);然后,重写实际上被绑定到使用新实例查看的命令。
如果有人有此问题,请确保在视图绑定的同一个实例上调用RelayCommand.RaiseCanExecuteChanged()。
发布于 2021-10-11 15:14:02
对于其他面临同样问题和接受答案的人来说,这对我没有任何帮助(对于我自己的记录来说,就像我今天花了几个小时在这上面一样)。
如果在VSTO外接程序中使用MVVM,请确保Office应用程序有机会处理自己的消息以使其工作。例如,在我的例子中,我让我的丝带按钮监听底层VM的命令对象的CanExecuteChanged,不管我做了什么,它都不会触发。花了几个小时之后,我意识到我必须让Office应用程序喘口气,处理传入的消息,这样才能让CanExecuteChanged被外接程序捕获。然后我所做的就是将我的RaiseCanExecuteChanged函数交给DispatcherHelper,让它异步地触发。直到那时,我的丝带按钮才开始对CanExecuteChanged事件做出反应。就像这样:
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
doc.Activate();
ResetVariablesCommand.RaiseCanExecuteChanged();
});https://stackoverflow.com/questions/6933427
复制相似问题