2011-09-07 81 views
5

使用ICommand對象的CanExecuteCommand會帶來怎樣的性能影響。該方法是否一遍又一遍地執行?CanExecuteCommand有任何性能影響?

我需要迭代約200個對象的集合,根據它來決定綁定到Command的按鈕是否應該啓用?是否CanExecuteCommand反覆地執行,這將讓我的應用程序的速度

+4

是的,但前提是您不提前優化。 – Will

+0

您的評論會有點含糊。 – Tyrsius

+0

請問,我也不完全明白。我的驗證是大約200個對象的迭代 - 樹視圖。它只是檢查一個簡單的屬性,並且在運行一次時不會非常耗時。 我的擔心是如果CanExecute被重複觸發使代碼變慢。有人可以拋出一些燈光 – ganeshran

回答

13

ICommand界面如下:

public interface ICommand 
{ 
    // two methods 
    bool CanExecute(object parameter); 
    void Execute(object parameter); 

    // one event 
    event EventHandler CanExecuteChanged; 
} 

CanExecuteChanged事件應提高要表明CanExecute方法應檢查任何時間/由WPF調用。實施ICommand的人應該引發該事件,並且需要刷新GUI(WPF系統)上的按鈕啓用狀態的人員應該註冊並處理事件,並且它調用CanExecute

在約什 - 史密斯的RelayCommand類,他使用WPF的內置CommandManager課堂上提出CanExecuteChanged

public event EventHandler CanExecuteChanged 
{ 
    add { CommandManager.RequerySuggested += value; } 
    remove { CommandManager.RequerySuggested -= value; } 
} 

從本質上說,WPF的CommandManager是一個單是聆聽各種路由事件:KeyUpEvent,MouseUpEvent,等等......然後通過提高其RequerySuggested事件告訴每個人「嗨發生了一些有趣的事情」。因此,如果您使用的是RelayCommand,那麼您的CanExecute每次都會在CommandManager認爲在GUI上發生了一些有趣的事情(即使它與您的收藏無關)。如果你有50條命令,每次鍵入時,它會重新檢查所有50條命令。所以是的,這可能是一個性能問題。但是,如果您的CanExecute方法中的邏輯非常簡單,那麼這可能不是問題。建議點:不要在CanExecute方法中進行數據庫或網絡API調用。

以捎帶關閉CommandManager.RequerySuggested提高ICommand.CanExecuteChanged事件的另一種方法是手工卷制自己的RelayCommand版本,你做你自己的檢查和人工提高CanExecuteChanged,或看棱鏡框架的DelegateCommand類,他們不打領帶到CommandManager,您必須手動提高CanExecuteChanged事件,您可以通過創建PropertyChanged的偵聽器,然後在該命令上增加CanExecuteChanged來完成該事件。

雖然我同意@Will的意思。 RelayCommand可能會工作超過80%的時間沒有問題。如果您確實開始發現性能問題,那麼您可以創建自己的RelayCommand版本,或者使用Prism DelegateCommand並手動提升CanExecuteChanged

+0

相關的答案在這裏:http://stackoverflow.com/questions/6634777/what-is-the-actual-task-of-canexecutechanged-and-commandmanager-requerysuggested – Kendrick

+0

謝謝肯德里克和威爾,你的回答總結爲我。我將把它放在CanExecute中並尋找任何性能滯後。如果我找到一個,那麼會查看其他實現 – ganeshran

0

對於未來的谷歌瀏覽器: 我創建了一個有點不同的命令實現。首先,它綁定到ViewModelBase類的OnPropertyChanged事件,但它也允許View模型爲其中的所有Command實例引發CanExecuteChanged事件,而不管屬性是否改變,例如One Way到源綁定方案。 此解決方案是PerrypheralFrameowrk.WPF程序集的一部分,可在nuget和codeplex上使用。看看它。 codeplex wiki有詳細的文檔,組件中的類也是如此。