![](/img/trans.png)
[英]MVVM Light - usage of RaiseCanExecuteChanged for RelayCommand
[英]RelayCommand RaiseCanExecuteChanged() fails
我正在使用幾個綁定到用 CanExecute 委托初始化的 RelayCommand 的按鈕。
RelayCommand DeleteCommand;
bool CanDelete()
{
return BoolProp1 && BoolProp2;
}
...
DeleteCommand = new RelayCommand(Delete, CanDelete);
BoolProp1
和BoolProp2
是設置器正確引發PropertyChanged
的常規屬性,但眾所周知,這不足以讓 SL 在命令上重新評估CanExecute
。 這就是為什么我也在兩個設置器中調用Delete.RaiseCanExecuteChanged()
的原因。
所有這些工作正常(按鈕被禁用和正確啟用)到某個點,所有停止的地方。 那時,調用Delete.RaiseCanExecuteChanged()
不再觸發我在CanDelete()
中的斷點,並且按鈕永遠保持原樣。
我花了 2 個小時試圖找出確切的原因,但沒有效果。 我懷疑在單個“綁定迭代”期間多次調用RaiseCanExecuteChanged()
以某種方式破壞了該機制。
有什么提示嗎? 我已經在考慮使用通過INotifyPropertyChanged
刷新的附加IsExecutable
字段 ...
更新
RelayCommand
實際上是來自MVVM Light Toolkit的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>
設置一次傳遞給構造函數的值。
我仍在努力以最低限度地重現該問題。
更新
看我的回答。
PEBKAC。 在某些情況下我的框架運行代碼
DeleteCommand = new RelayCommand(Delete, CanDelete);
多一次,覆蓋實際綁定到新實例查看的命令。
如果有人遇到此問題 - 請確保在視圖綁定的同一實例上調用RelayCommand.RaiseCanExecuteChanged()
。
對於遇到同樣問題並且接受的答案對我沒有幫助的任何其他人(以及我自己的記錄,因為我今天花了幾個小時)。
如果您在 VSTO 加載項中使用 MVVM Light,請確保 Office 應用程序有機會處理自己的消息以使其正常工作。 例如,在我的例子中,我的功能區按鈕偵聽底層 VM 命令對象的CanExecuteChanged
,無論我做什么都不會觸發。 花了幾個小時后,我意識到我必須讓 Office 應用程序喘口氣並處理傳入的消息,以允許加載項捕獲CanExecuteChanged
。 然后我所做的是將我的RaiseCanExecuteChanged
function 交給DispatcherHelper
讓它異步觸發。 直到那時我的功能區按鈕才開始對CanExecuteChanged
事件做出反應。 是這樣的:
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
doc.Activate();
ResetVariablesCommand.RaiseCanExecuteChanged();
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.