c# - 将 WeakEventManager 与静态事件一起使用

标签 c# wpf silverlight

是否可以使用 Wea​​kEventManager 在静态事件上创建弱事件监听器?

我想在静态 CompositionTarget.Rendering 事件上创建一个弱事件监听器,以避免在我不知道 WPF/Silverlight 源元素的生命周期时发生内存泄漏。

我通过 weak event pattern 实现了渲染事件管理器:

public class RenderingEventManager : WeakEventManager
{
    public static void AddListener(IWeakEventListener listener)
    {
        CurrentManager.ProtectedAddListener(null, listener);
    }

    public static void RemoveListener(IWeakEventListener listener)
    {
        CurrentManager.ProtectedRemoveListener(null, listener);
    }

    private static RenderingEventManager CurrentManager
    {
        get
        {
            var managerType = typeof(RenderingEventManager);
            var manager = (RenderingEventManager)GetCurrentManager(managerType);
            if (manager == null)
            {
                manager = new RenderingEventManager();
                SetCurrentManager(managerType, manager);
            }
            return manager;
        }
    }

    protected sealed override void StartListening(object source)
    {
        CompositionTarget.Rendering += this.OnCompositionTargetRendering;
    }

    protected sealed override void StopListening(object source)
    {
        CompositionTarget.Rendering -= this.OnCompositionTargetRendering;
    }

    void OnCompositionTargetRendering(object sender, EventArgs e)
    {
        this.DeliverEvent(sender, e);
    }
}

并在一个简单的窗口中测试管理器:

public partial class Window1 : Window, IWeakEventListener
{
    public Window1()
    {
        InitializeComponent();
        RenderingEventManager.AddListener(this);
    }

    bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
    {
        return true;
    }
}

没有调用 ReceiveWeakEvent 方法。调用了 OnCompositionTargetRendering,但 DeliverEvent 似乎没有像我预期的那样工作。 向 Button.Click 等实例事件添加监听器效果很好...... 测试项目在 .NET 4.0 Client Profile 上。

A post on Microsoft Connect from 2009声明不支持静态事件, 但我检查了 WeakEventManager 源代码,看起来没问题:

    protected void ProtectedAddListener(object source, IWeakEventListener listener) 
    { 
        Debug.Assert(listener != null, "Listener cannot be null");

        object sourceKey = (source != null) ? source : StaticSource;
        ...
    }

最佳答案

我自己想出来了:将 DeliverEvent 方法的 sender 参数更改为 null:

void OnCompositionTargetRendering(object sender, EventArgs e)
{
    this.DeliverEvent(null, e);
}

关于c# - 将 WeakEventManager 与静态事件一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8876112/

相关文章:

c# - 此上下文中不存在名称 SpaceProcessingModeValues

c# - 为什么 c# : String and string 中有两个关键字

c# - 从进程外 C++ COM 获取字节数组到 C#

c# - DataGrid 列标题与数据不对齐

c# - 绑定(bind)到 ItemsSource 中的属性

c# - 在动态创建的文本框的代码隐藏中将文本框的高度设置为自动

silverlight - Silverlight/XAML 中的水平规则

c# - ASP.NET MVC 2 过滤多个下拉列表

wpf - 更改缩放顺序 WPF

wpf - 使用存储库模式时我们是否需要重新创建模型类