Wpf Microsoft.Win32.SystemEvents事件不';Don’’我不能和温特经理一起工作
当我这样做的时候Wpf Microsoft.Win32.SystemEvents事件不';Don’’我不能和温特经理一起工作,wpf,weak-events,weakeventmanager,Wpf,Weak Events,Weakeventmanager,当我这样做的时候 WeakEventManager<SystemEvents, EventArgs> .AddHandler(null, nameof(SystemEvents.DisplaySettingsChanged), OnDisplaySettingsChanged); ventManager .AddHandler(null,nameof(SystemEvents.DisplaySettingsChanged),OnDisplaySettingsChanged)
WeakEventManager<SystemEvents, EventArgs>
.AddHandler(null, nameof(SystemEvents.DisplaySettingsChanged), OnDisplaySettingsChanged);
ventManager
.AddHandler(null,nameof(SystemEvents.DisplaySettingsChanged),OnDisplaySettingsChanged);
MyOnDisplaySettingsChanged
从未被调用。但是,如果我改为通过SystemEvents.DisplaySettingsChanged+=OnDisplaySettingsChanged
使用普通事件订阅,则一切正常
发生了什么事?原来是
薄弱的管理员的错。触发事件时,表示静态事件源的source
将为null
(代码摘录自):
但是SystemEvents
的sender
从不为null
。相反,它传递一个SystemEvents
的私有实例,WeakEventManager
然后假设它是另一个它以前不知道的实例,并且不调用处理程序
以下是我提出的解决方法:
class EventProxy
{
private readonly Action<EventHandler> _subscribe;
private readonly Action<EventHandler> _unsubscribe;
public EventProxy(Action<EventHandler> subscribe, Action<EventHandler> unsubscribe)
{
_subscribe = subscribe;
_unsubscribe = unsubscribe;
}
private EventHandler _event;
public event EventHandler Event
{
add
{
if (_event == null)
_subscribe(OnEvent);
_event += value;
}
remove
{
// ReSharper disable once DelegateSubtraction
_event -= value;
if (_event == null)
_unsubscribe(OnEvent);
}
}
private void OnEvent(object sender, EventArgs args)
{
_event?.Invoke(this, args);
}
}
class事件代理
{
私有只读操作_订阅;
私人只读操作_取消订阅;
公共事件代理(操作订阅、操作取消订阅)
{
_订阅=订阅;
_退订=退订;
}
私有EventHandler\u事件;
公共事件处理程序事件
{
添加
{
如果(_event==null)
_订阅(OneEvent);
_事件+=值;
}
去除
{
//ReSharper禁用一次委派减法
_事件-=值;
如果(_event==null)
_取消订阅(OneEvent);
}
}
私有void OneEvent(对象发送方、事件参数)
{
_事件?.Invoke(这个,args);
}
}
用法示例:
var proxy = new EventProxy(h => SystemEvents.DisplaySettingsChanged += h, h => SystemEvents.DisplaySettingsChanged -= h);
WeakEventManager<EventProxy, EventArgs>.AddHandler(proxy, nameof(EventProxy.Event), OnDisplaySettingsChanged);
var proxy=neweventproxy(h=>SystemEvents.DisplaySettingsChanged+=h,h=>SystemEvents.DisplaySettingsChanged-=h);
WeakEventManager.AddHandler(代理、名称(EventProxy.Event)、OnDisplaySettingsChanged);
一些解释:
SystemEvents
包含对EventProxy
的强引用,后者包含对处理程序的弱引用(通过WeakEventManager
)
- 当
WeakEventManager
订阅AddHandler
中的事件时,代理订阅原始事件
EventProxy
充当静态事件和处理程序之间的代理,在原始事件激发时调用处理程序
- 收集处理程序后,
WeakEventManager
最终将运行清理,发现处理程序已死亡并取消订阅
- 这将导致代理取消订阅原始事件,并最终被GC收集
var proxy = new EventProxy(h => SystemEvents.DisplaySettingsChanged += h, h => SystemEvents.DisplaySettingsChanged -= h);
WeakEventManager<EventProxy, EventArgs>.AddHandler(proxy, nameof(EventProxy.Event), OnDisplaySettingsChanged);