public HandlerSink(CanExecuteChangedEventManager manager, ICommand source, EventHandler <EventArgs> originalHandler) { _manager = manager; _source = new WeakReference(source); _originalHandler = new WeakReference(originalHandler); // In WPF 4.0, elements with commands (Button, Hyperlink, etc.) listened // for CanExecuteChanged and also stored a strong reference to the handler // (in an uncommon field). Some third-party commands relied on this // undocumented implementation detail by storing a weak reference to // the handler. (One such example is Win8 Server Manager's DelegateCommand - // Microsoft.Management.UI.DelegateCommand<T> - see Win8 Bugs 588129.) // // Commands that do this won't work with normal listeners: the listener // simply calls command.CanExecuteChanged += new EventHandler(MyMethod); // the command stores a weak-ref to the handler, no one has a strong-ref // so the handler is soon GC'd, after which the event doesn't get // delivered to the listener. // // In WPF 4.5, Button et al. use this weak event manager to listen to // CanExecuteChanged, indirectly. Only the manager actually listens // directly to the command's event. For compat, the manager stores a // strong reference to its handler. The only reason for this is to // support those commands that relied on the 4.0 implementation. _onCanExecuteChangedHandler = new EventHandler(OnCanExecuteChanged); // BTW, the reason commands used weak-references was to avoid leaking // the Button - see Dev11 267916. This is fixed in 4.5, precisely // by using the weak-event pattern. Commands can now implement // the CanExecuteChanged event the default way - no need for any // fancy weak-reference tricks (which people usually get wrong in // general, as in the case of DelegateCommand<T>). // register the local listener source.CanExecuteChanged += _onCanExecuteChangedHandler; }
public HandlerSink(CanExecuteChangedEventManager manager, ICommand source, EventHandler<EventArgs> originalHandler) { _manager = manager; _source = new WeakReference(source); _originalHandler = new WeakReference(originalHandler); // In WPF 4.0, elements with commands (Button, Hyperlink, etc.) listened // for CanExecuteChanged and also stored a strong reference to the handler // (in an uncommon field). Some third-party commands relied on this // undocumented implementation detail by storing a weak reference to // the handler. (One such example is Win8 Server Manager's DelegateCommand - // Microsoft.Management.UI.DelegateCommand<T> - see Win8 Bugs 588129.) // // Commands that do this won't work with normal listeners: the listener // simply calls command.CanExecuteChanged += new EventHandler(MyMethod); // the command stores a weak-ref to the handler, no one has a strong-ref // so the handler is soon GC'd, after which the event doesn't get // delivered to the listener. // // In WPF 4.5, Button et al. use this weak event manager to listen to // CanExecuteChanged, indirectly. Only the manager actually listens // directly to the command's event. For compat, the manager stores a // strong reference to its handler. The only reason for this is to // support those commands that relied on the 4.0 implementation. _onCanExecuteChangedHandler = new EventHandler(OnCanExecuteChanged); // BTW, the reason commands used weak-references was to avoid leaking // the Button - see Dev11 267916. This is fixed in 4.5, precisely // by using the weak-event pattern. Commands can now implement // the CanExecuteChanged event the default way - no need for any // fancy weak-reference tricks (which people usually get wrong in // general, as in the case of DelegateCommand<T>). // register the local listener source.CanExecuteChanged += _onCanExecuteChangedHandler; }