删除带有某些参数的匿名事件处理程序



我订阅了这样的事件:

private void CoupleOverlay(IMapVisual mapVisual)
{            
      overlay.DrawTilesProgressChanged += (s, e) => 
      {               
          mapVisual.DrawingProgress = e.ProgressPercentage;
      };
}

应用程序可能会多次调用 CoupleOverlay 事件,因此我需要取消订阅 DrawTilesProgressChanged 事件并再次订阅,但由于它是一个匿名事件,我无法取消订阅它。我试图转换为

private void CoupleOverlay(IMapVisual mapVisual)
{
    overlay.DrawTilesProgressChanged -=overlay_DrawTilesProgressChanged;                 
    overlay.DrawTilesProgressChanged +=overlay_DrawTilesProgressChanged;                 
}
private void overlay_DrawTilesProgressChanged(object sender, DrawTilesProgressChangedTileOverlayEventArgs e)
{       
    mapVisual.DrawingProgress = e.ProgressPercentage;
}

它不起作用mapVisual因为该方法overlay_DrawTilesProgressChanged上变量无效。

如果我将代码更改为

private void CoupleOverlay(IMapVisual mapVisual)
{
    EventHandler<DrawTilesProgressChangedTileOverlayEventArgs> drawEvent = (s, e) =>
    {           
        mapVisual.DrawingProgress = e.ProgressPercentage;
    };
    overlay.DrawTilesProgressChanged -= drawEvent;
    overlay.DrawTilesProgressChanged += drawEvent;
}

它不起作用,因为drawEvent是一个局部变量,下次我调用 CoupleOverlay 时,它会创建一个新的变量。

那么如何取消订阅此事件处理程序呢?或者我如何知道我已订阅该活动,因此我不需要再次订阅?

它不起作用,因为drawEvent是局部变量,下次我调用CoupleOverlay时,它将创建一个新的变量。

事实上。您基本上需要保留一个实例变量而不是局部变量。实例变量实际上是"当前订阅的事件处理程序"。然后在CoupleOverlay中删除该事件处理程序,创建一个新的事件处理程序(将其存储在变量中)并重新订阅它。

另一种方法是使用单个事件处理程序,但将"当前"覆盖和映射视觉对象保留为事件处理程序使用的实例变量。然后,CoupleOverlay方法只需要更新这些变量。

如何取消订阅此事件处理程序

你不能,因为 lambda 是一个局部变量,不能超出声明它的范围(在函数本身中,在你的例子中)。要获得所需的灵活性,您需要利用delegates

如何理解我已订阅和活动,所以我不需要 再次订阅

要获取订阅者列表,只需使用:

MulticastDelegate.GetInvocationList 方法(事件和委托是多播)

相关内容

  • 没有找到相关文章

最新更新