是否有普遍接受的最佳实践来创建自行取消订阅的事件处理程序?
例如,我想到的第一件事是:
// Foo.cs
// ...
Bar bar = new Bar(/* add'l req'd state */);
EventHandler handler = new EventHandler(bar.HandlerMethod);
bar.HandlerToUnsubscribe = handler;
eventSource.EventName += handler;
// ...
// Bar.cs
class Bar
{
/* add'l req'd state */
// .ctor
public EventHandler HandlerToUnsubscribe { get; set; }
public void HandlerMethod(object sender, EventArgs args)
{
// Do what must be done w/ add'l req'd state
((EventSourceType)sender).EventName -= this.HandlerToUnsubscribe;
}
}
说这感觉很糟糕/很糟糕是轻描淡写的。它与时间依赖性紧密耦合(HandlerToUnsubscribe
必须在正确的时间分配准确的值)。我觉得在这种情况下我一定扮演了一个复杂化者的角色——我是否遗漏了一些愚蠢或简单的东西?
Context:
我正在 Winforms 中创建 UI 和专有命令基础结构之间的绑定(使用有用的ICommand
在系统.Windows.输入中)。绑定基础设施的一个方面是,在 UI 命令组件(如工具栏按钮或菜单项)之间创建绑定的用户可以选择监听命令的CanExecuteChanged
事件,然后根据该事件更新 UI 的状态 - 通常将 Enabled 属性设置为true
or false
.
该技术通常工作得很好,但有一些方法可以在创建 ui 组件的句柄之前触发事件。我试图保证提供的处理程序不会运行,除非已创建句柄。因此,我正在考虑提供一个通用的帮助类(“Bar
“)这将有助于实施。目标Bar
是检查是否存在适当的句柄。如果是这样,那就太好了!如果没有,它将订阅适当的IsHandleCreated
事件,以便在最终创建句柄时运行提供的处理程序。 (这很重要,因为客户端可以在句柄存在之前在 UI 的 .ctor 中设置其绑定。)但是,我希望此订阅完全透明,因此我也希望每个事件处理程序自动取消订阅IsHandleCreated
一旦运行完成。
我仍然在试图弄清楚这是否是一个好主意,所以我还没有概括这个概念 - 在这种情况下我只是直接针对 ToolStripItems 实现它来验证这个想法是健全的。不过,我还没有相信它。
据我了解,我还可以选择简单地强制只能在创建 UI 句柄后(在表单的 OnLoad 事件中)创建绑定(例如)。我知道这可行,我过去就这么做过。我想看看在这种情况下我是否可以放松这一特定要求。如果还实用的话。