2010-07-12 61 views
1

(背景:我將一個WinForms應用程序分階段移植到WPF中。目前,我仍然有一個WinForms主表單,其中包含一個包含WPF內容的ElementHost。RoutedCommand.CanExecuteChanged事件在ElementHost內部並不一致觸發

我想我的應用程序被告知當某些ApplicationCommandsCutCopyPaste改變他們的.CanExecute的價值。我認爲訂閱像ApplicationCommands.Cut.CanExecuteChanged這樣的全局事件是一件簡單的事情,但我注意到一些似乎並沒有被一致調用的奇怪行爲。

例如,我創建了一個簡單的WinForms測試應用程序,它只是一個ElementHost。然後我添加了一個WPF文本框,並附加CanExecuteChanged處理它:

public Form1() 
{ 
    InitializeComponent(); 

    var tb = new System.Windows.Controls.TextBox {Text = "WPF Inside ElementHost"}; 

    ApplicationCommands.Cut.CanExecuteChanged += Cut_CanExecuteChanged; 
    ApplicationCommands.Cut.CanExecuteChanged += 
     (s, e) => Debug.WriteLine("CanExecute Changed=" + ApplicationCommands.Cut.CanExecute(null, s as IInputElement)); 

    elementHost1.Child = tb; 
} 

private void Cut_CanExecuteChanged(object sender, System.EventArgs e) 
{ 
    Debug.WriteLine("CanExecute Method for Cut = " + ApplicationCommands.Cut.CanExecute(null, sender as IInputElement)); 
} 

的奇怪的事情是,當我做這樣的事情在文本框中選擇文本使用內嵌的λ/委託處理程序被調用。但是,使用實例方法訂閱的那個不會被調用。

此外,在我的更復雜的應用程序中,即使我爲處理程序使用內聯委託,我也沒有看到CanExecute完全被調用。

+0

當我閱讀http://meta.stackexchange.com/questions/17845/stack-overflow-etiquette-for-answering-your-own-question,然後決定繼續前進時,我即將完全刪除這個問題,提交它希望它可以幫助別人。 – 2010-07-12 18:18:30

回答

3

(在使用的StackOverflow爲rubber duck的情況下,我認識了答案,當我寫完這個問題)

雖然有點繞reflector'ing,我看到CanExecuteChanged事件只是將處理程序CommandManager.RequerySuggested 。因爲後面這個事件是一個靜態事件,所以它會使用WeakReference處理程序,並在引發事件時修剪該列表。由於我並沒有在課堂上保留一個強硬的參考文獻,所以GC發現參考文獻不再有效並正在被修剪。

解決方案只是添加一個具有EventHandler的類成員變量,然後在附加事件時使用該成員變量引用。

相關問題