2011-08-03 44 views
3

我正在使用几个Buttons绑定到使用CanExecute委托初始化的RelayCommands。RelayCommand RaiseCanExecuteChanged()失败

RelayCommand DeleteCommand; 
bool CanDelete() 
{ 
    return BoolProp1 && BoolProp2; 
} 

... 

DeleteCommand = new RelayCommand(Delete, CanDelete); 

BoolProp1BoolProp2是常规性质与制定者正确地提高PropertyChanged,但大家都知道,这是不够的,使SL重新评估CanExecute上的命令。这就是为什么我也在两个调用者中调用Delete.RaiseCanExecuteChanged()

所有这些工作正常(按钮被禁用和正确启用)直到某一点,所有停止的地方。此时,拨打Delete.RaiseCanExecuteChanged()不再触发我在CanDelete()中的断点,按钮将永远保持原有状态。

我花了2个小时试图隔离确切的原因,没有效果。我怀疑单个“绑定迭代”期间调用多个RaiseCanExecuteChanged()会以某种方式破坏机制。

任何提示?我已经在考虑使用附加IsExecutable场刷新通过INotifyPropertyChanged ...

UPDATE

RelayCommand实际上GalaSoft.MvvmLight.Command.RelayCommandMVVM Light Toolkit。 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>设置一次传递给构造函数的值。

我仍在努力最小程度地重现问题。

UPDATE

见我的答案。

+1

发布更多验证码。什么是RelayCommandEx?这个命令的实现是什么样的?如果可能,创建一个非常简单的repro并发布完整代码。 –

+0

''RelayCommandEx''是我处理失败的尝试(尝试缓存CanExecute()值,如果不需要,则不会触发CanExecuteChanged)。 –

+1

我有一个模糊的记忆,碰到这个,它必须做的东西(我认为在我的情况下,这是WPF按钮)没有缓存EventHandler和弱引用。试图弄清楚我有空时是什么,但可能有助于你走上正确的道路。您可能希望实现CanExecuteChanged事件的添加/删除访问器,然后在删除中设置断点以查看删除时间。 – CodeNaked

回答

6

PEBKAC。我在某些情况下框架运行的代码

DeleteCommand = new RelayCommand(Delete, CanDelete); 

多于一次,覆盖掉实际上必然要查看与新实例的命令。

如果有人有这个问题 - 确保你在视图绑定的同一个实例上调用RelayCommand.RaiseCanExecuteChanged()