如何取消注册在 xaml 中创建的没有名称的项的事件

本文关键字:创建 有名称 事件 xaml 何取消 取消 注册 | 更新日期: 2023-09-27 18:31:29

因此,当我们的应用程序开始使用大量内存时,我们将返回并尝试清理代码中的某些内容。在阅读有关 WPF 和内存管理的信息后,我们发现事件处理程序是最大的违规者之一。因此,我们已经知道它破坏了具有处理程序的 MVVM。当我们摆脱控制时,我们如何取消注册事件。

例如,如果我们在 TabControl 中有一个用户控件,并且我们关闭了该选项卡 - 我们知道我们可以注销所有事件;但是,用户控件没有任何名称。我想返回并向这些控件添加名称很容易,但是有没有办法在不使用名称的情况下做到这一点?

下面是指向控件的链接。我使用了粘贴箱,因为它的字符太多,无法在此处发布。通过此控件,我们看到了内存中最大的跳跃。

如何取消注册在 xaml 中创建的没有名称的项的事件

使用:

foreach (var control in myTabControl.FindDescendents<UserControl>())
{
    control.EventName -= MyEventHandler;
}

其中DependencyObject.FindDescendants<T>()扩展方法在静态类中定义:

public static IEnumerable<T> FindDescendants<T>(this DependencyObject parent) where T : DependencyObject 
{
    return FindDescendants<T>(parent, null, false);
}
public static IEnumerable<T> FindDescendants<T>(this DependencyObject parent, Func<T, bool> predicate) where T : DependencyObject 
{
    return FindDescendants(parent, predicate, false);
}
public static IEnumerable<T> FindDescendants<T>(this DependencyObject parent, bool deepSearch) where T : DependencyObject 
{
    return FindDescendants<T>(parent, null, deepSearch);
}
public static IEnumerable<T> FindDescendants<T>(this DependencyObject parent, Func<T, bool> predicate, bool deepSearch) where T : DependencyObject 
{
    var children = LogicalTreeHelper.GetChildren(parent).OfType<DependencyObject>().ToList();
    foreach (var child in children) 
    {
        var typedChild = child as T;
        if (typedChild != null && (predicate == null || predicate.Invoke(typedChild))) 
        {
            yield return typedChild;
            if (deepSearch) 
            {
                foreach (var foundDescendant in FindDescendants(child, predicate, true)) yield return foundDescendant;
            }
        } 
        else 
        {
            foreach (var foundDescendant in FindDescendants(child, predicate, deepSearch)) yield return foundDescendant;
        }
    }
}

(当然,您可以只有一种扩展方法 - 我冒昧地从具有这些重载版本的库中复制和粘贴。