Wpf RoutedCommand.CanExecuteChanged事件在ElementHost内部不一致地触发

Wpf RoutedCommand.CanExecuteChanged事件在ElementHost内部不一致地触发,wpf,routed-commands,Wpf,Routed Commands,(背景:我正在分阶段将WinForms应用程序移植到WPF。目前,我仍然有一个WinForms主窗体,其中有一个包含WPF内容的ElementHost。) 我希望我的应用程序在某些情况下(例如)被告知,并更改其.CanExecute的值。我原以为订阅ApplicationCommands.Cut.CanExecuteChanged这样的全局事件很简单,但我注意到一些奇怪的行为,似乎没有一致地调用它 例如,我创建了一个简化的WinForms测试应用程序,它只有一个ElementHost。然后,我向

(背景:我正在分阶段将WinForms应用程序移植到WPF。目前,我仍然有一个WinForms主窗体,其中有一个包含WPF内容的ElementHost。)

我希望我的应用程序在某些情况下(例如)被告知,并更改其.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));
}
奇怪的是,当我在文本框中选择文本之类的操作时,会调用使用内联lambda/delegate的处理程序。但是,不会调用使用实例方法订阅的实例

此外,在我更复杂的应用程序中,我根本看不到调用CanExecute,即使我为处理程序使用了内联委托。

(在使用StackOverflow作为代理的情况下,我在写完问题后意识到了答案)

当反射器来回走动时,我看到CanExecuteChanged事件只是将处理程序传递给。因为后面的事件是一个静态事件,所以它在引发事件时使用处理程序并修剪列表。由于我没有在类中保留硬引用,GC检测到该引用不再有效,并且正在被删除


解决方案只是添加一个具有EventHandler的类成员变量,然后在附加事件时使用该成员变量引用

当我读到这篇文章时,我正打算把这个问题全部删除,然后决定继续提交,希望它能帮助其他人。