1

我订阅了这样的活动:

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 时,它将创建一个新变量。

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

4

2 回答 2

1

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

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

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

于 2012-05-16T14:23:44.747 回答
1

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

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

我怎么知道我已订阅和活动,所以我不需要再次订阅

要获取订阅者列表,使用以下内容就足够了:

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

于 2012-05-16T14:24:41.627 回答