正在取消订阅UWP中自定义工具提示和自定义弹出类中的事件



我正在尝试创建自己的自定义ToolTip类,在构造函数中注册Loading事件。如何取消订阅此活动?当我在终结器/析构函数中执行此操作时,它会导致异常,尤其是当我打开应用程序的新窗口并关闭它时:

COM对象已与其基础RCW分离,无法使用。

这是我的代码:

public class CustomToolTip: ToolTip
{
public CustomToolTip()
{
this.Loading += CustomToolTip_Loading;
}
protected void CustomToolTip_Loading(Windows.UI.Xaml.FrameworkElement sender, object args)
{
// my logic here
}
~CustomToolTip()
{
this.Loading -= CustomToolTip_Loading;
}
}

当我创建自定义Flyout控件并尝试取消订阅终结器中的Opening事件时,也会发生此异常。

我的代码:

public class CustomFlyout: Flyout
{
public CustomFlyout()
{
this.Opening += CustomFlyout_Opening;
}
private void CustomFlyout_Opening(object sender, object e)
{
// my logic here
}
~CustomFlyout()
{
this.Opening -= CustomFlyout_Opening;
}
}

任何帮助都将不胜感激。

除非直接处理非托管资源,否则不应该在类中定义终结器。

如果您只想处理一次事件,而不管您的控件加载了多少次,那么当Loading事件被引发时,您可以简单地注销事件处理程序:

public class CustomToolTip : ToolTip
{
public CustomToolTip()
{
this.Loading += CustomToolTip_Loading;
}
protected void CustomToolTip_Loading(Windows.UI.Xaml.FrameworkElement sender, object args)
{
this.Loading -= CustomToolTip_Loading;
//...
}
}

否则,会出现Unloading事件:

private void CustomToolTip_Unloaded(object sender, RoutedEventArgs e)
{
this.Loading -= CustomToolTip_Loading;
this.Unloaded -= CustomToolTip_Unloaded;
}

还要注意,只有当发布服务器的寿命比订阅服务器的寿命长时,从事件中注销以避免内存泄漏才是重要的。

正如T.Schwarz所说,如果仍然有对对象的引用,它将永远无法执行终结器。因此,您需要在其他地方删除eventHandlers,例如Dispose方法。

public class CustomToolTip : ToolTip,IDisposable
{
……
public void Dispose()
{
this.Loading -= CustomToolTip_Loading;
}

}

最新更新