我订阅了这样的事件:
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 方法(事件和委托是多播)