2

2 つの ViewModel があり、1 つに別の ViewModel が含まれています。内側のものにはMicrosoft.Practices.Prism.Commands.DelegateCommandと呼ばれるものがありPrintCommandます。CanExecuteChangedこのコマンドのイベントにサブスクライブすることが望ましいです。この部分は通常どおり実装されます。

OneViewModel.PrintCommand.CanExecuteChanged += CanExecuteChangedHandler;  

問題は、このサブスクリプションが機能しないことです。逆コンパイルCanExecuteChangedすると次のようになります。

public event EventHandler CanExecuteChanged  
{  
  add  
  {  
    WeakEventHandlerManager.AddWeakReferenceHandler(ref this._canExecuteChangedHandlers, value, 2);  
  }  
  remove  
  {  
    WeakEventHandlerManager.RemoveWeakReferenceHandler(this._canExecuteChangedHandlers, value);  
  }  
}  

デバッグすると、サブスクライバー オブジェクトがまだ存在していても、サブスクリプション後のいくつかの手順の後、_canExecuteChangedHandlersアクティブなハンドラーが含まれていないようです。
ちょっと気になるのですが、どうしてこうなったのですか?

4

1 に答える 1

2

の説明に答えがありましたCanExecuteChanged。ここにあります:

/// When subscribing to the <see cref="E:System.Windows.Input.ICommand.CanExecuteChanged"/> event using
///             code (not when binding using XAML) will need to keep a hard reference to the event handler. This is to prevent
///             garbage collection of the event handler because the command implements the Weak Event pattern so it does not have
///             a hard reference to this handler. An example implementation can be seen in the CompositeCommand and CommandBehaviorBase
///             classes. In most scenarios, there is no reason to sign up to the CanExecuteChanged event directly, but if you do, you
///             are responsible for maintaining the reference.

これは、ハード参照が必要であることを意味します。

private readonly EventHandler commandCanExecuteChangedHandler;

そして、次のように使用します。

this.commandCanExecuteChangedHandler = new EventHandler(this.CommandCanExecuteChanged);
this.command.CanExecuteChanged += this.commandCanExecuteChangedHandler;
于 2015-01-23T08:16:18.073 に答える