从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件

Posted

技术标签:

【中文标题】从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件【英文标题】:Unsubscribing events from custom ToolTip and custom Flyout class in UWP 【发布时间】:2021-08-19 08:34:33 【问题描述】:

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

无法使用已与其底层 RCW 分离的 COM 对象。

这是我的代码:

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;
    

任何帮助将不胜感激。

【问题讨论】:

清理终结器中的事件对我来说没有多大意义,因为如果由于事件引用而无法清理对象,除非我遗漏了什么,否则终结器将不会被调用。我会实现 IDisposable 但您也可以在 Unloaded 事件中将事件设置为 null。 【参考方案1】:

你不应该在你的类中定义终结器,除非你直接处理你在这里肯定没有的非托管资源。

如果您只想处理一次事件而不管控件加载多少次,您可以在引发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;

另请注意,仅当发布者的寿命长于订阅者时,从事件中取消注册以避免内存泄漏才重要。

【讨论】:

【参考方案2】:

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

public class CustomToolTip : ToolTip,IDisposable
    
      ……

        public void Dispose()
        
            this.Loading -= CustomToolTip_Loading;
        
      
    

【讨论】:

那么是谁在打电话给Dispose()

以上是关于从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件的主要内容,如果未能解决你的问题,请参考以下文章

从代码绑定到 WinRT/UWP 中的自定义附加属性

UWP xamarin 中的自定义渲染器

text UWP中的自定义视图:ControlTemplate

Xamarin 表单:UWP 和 Windows 8.1 中的自定义字体

未找到具有自定义分页 404 的自定义分类和自定义帖子类型

带有 xib 文件和自定义构造函数的自定义 UITableViewCell