2016-11-14 51 views
2

我做了一些自定義的ICommand實現我自己的,我看到的實現會像這樣的很多:爲什麼人們在ICommands上使用CommandManager.InvalidateRequerySuggested()?

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

protected void RaiseCanExecuteChanged() 
{   
    CommandManager.InvalidateRequerySuggested(); 
} 

至於我可以看到,因爲調用RaiseCanExecuteChanged()將觸發所有的命令,這是優化不好的代碼用戶界面來檢查他們的ICommand.CanExecute狀態,通常我們只是想讓他們中的一個來驗證它。

我想我讀了一次,這是一些WPF ICommands的主代碼,比如RoutedCommand,對他們來說它是有道理的,因爲他們想要一旦某個控件失去焦點和像這樣的事情時自動重新驗證所有ICommands,不明白爲什麼人們將自己的模式重複用於他們自己的ICommand實現。

我心目中的代碼是一個簡單的事件調用,如:

public event EventHandler CanExecuteChanged; 

protected void RaiseCanExecuteChanged() 
{   
    CanExecuteChanged?.Invoke(this, EventArgs.Empty); 
} 

我測試,一切正常,所以爲什麼所有的網絡上的例子沒有實現這麼簡單的東西嗎?我錯過了什麼嗎?

我已閱讀有關使用視圖被垃圾收集在定期活動,其中CommandManager只使用WeakReferences,這是很好的情況下,強引用的內存泄漏問題,但儘管如此,不存在贏得任何解決方案」在性能上超越內存佔用?

+0

http://stackoverflow.com/questions/2281566/is-josh-smiths-implementation-of-the-relaycommand-flawed – ASh

回答

2

爲什麼網絡上的所有示例都沒有實現像這樣簡單的事情?我錯過了什麼嗎?

我猜這主要是由於懶惰...你提出的確實是一個更好的(更高效的)實現。但是,這並不完整:您仍然需要訂閱CommandManager.RequerySuggested以提高命令CanExecuteChanged

+0

爲什麼?我測試了這個,它的工作原理......我錯過了哪些情況? – mFeinstein

+0

@mFeinstein,在你測試的情況下,它「起作用」,但調用CommandManager.InvalidateRequerySuggested()不會在你的命令中引發CanExecuteChanged。 –

+0

我沒想到它會... – mFeinstein

1

非常簡單 - 如果您在ICommand.CanExecute()中執行繁重的工作,那麼您正在使用Commands非常糟糕。如果遵循該規則,則實際上不應該致電CommandManager.InvalidateRequerySuggested()

從實用角度來看,它比您所建議的要容易得多。

個人而言,我更傾向於在特定的ViewModel中撥打CommandManager.InvalidateRequerySuggested(),以便對用戶的反饋是即時的(即一旦表格完成/有效就啓用按鈕)。

+0

我很抱歉,但我不明白你的觀點,5線解決方案如何比「3線解決方案更容易編程」? – mFeinstein

+0

這很簡單,因爲您不必每次都在每個受該屬性影響的「Command」上調用'RaiseCanExecuteChanged'。 – toadflakz

+0

在這個意義上說,它是,但恕我直言,它的概念有缺陷。 RaiseCanExecuteChanged我相信ViewModel能夠通知特定的Command,只有他,他的CanExecute狀態發生了變化。 CommandManager是通知所有人的人。我無法想象任何編程的情況下,激活所有對象的目的是激活一個被認爲是好的做法。這就像在街上大喊大叫,所有人都會打開門,而不是在你想要的門鈴響起。但是,如果你保持你的CanExecute簡單並且命令很少,我仍然明白簡單。 – mFeinstein

相關問題