【发布时间】:2015-10-14 13:25:10
【问题描述】:
我的 Windows 窗体应用程序带有一个主窗体(从基础 Form 派生)。其他可以在那里打开的模态形式来源于我的类ManagedForm,也来源于Form。
我还有一个静态通知服务,它会触发一些这样的事件:
public static class NotifierService
{
public delegate void NotifierServiceEventHandler(object sender, NotifierServiceEventArgs e);
private static readonly object Locker = new object();
private static NotifierServiceEventHandler _notifierServiceEventHandler;
#region Events
public static event NotifierServiceEventHandler OnOk
{
add
{
lock (Locker)
{
_notifierServiceEventHandler += value;
if (
_notifierServiceEventHandler.GetInvocationList()
.Count(
_ =>
_.Method.DeclaringType != null &&
value.Method.DeclaringType != null &&
_.Method.DeclaringType == value.Method.DeclaringType) <= 1)
return;
_notifierServiceEventHandler -= value;
}
}
remove
{
lock (Locker)
{
_notifierServiceEventHandler -= value;
}
}
}
// and many more events similar to previous...
#endregion
#region Event firing methods
public static void NotifyOk(string fullMessage = "Ok.", string shortMessage = null)
{
NotifierServiceEventHandler handler;
lock (Locker)
{
handler = _notifierServiceEventHandler;
}
if (handler == null) return;
handler(typeof (NotifierService),
new NotifierServiceEventArgs(StatusType.Ok, fullMessage, shortMessage ?? fullMessage));
}
#endregion
}
因此,在某些代码位置,这些事件可能会像这样被触发:
NotifierService.NotifyExclamation("Fail!");
在主窗体中有StatusStrip 控件用于通知目的,并且由于主窗体订阅了这些事件——它们的消息将显示在状态条中。
但是!,正如我之前所说,用户可以打开其他表单,这些表单可以生成其他表单,依此类推......(它们来自一个类ManagedForm,它将被订阅到NotifierService已创建)。
在这些表单中,还有另一种逻辑如何通知用户——他们需要向MessageBoxes 显示消息。正如你所看到的,我在事件访问器中添加了一些魔法,只允许任何类型的一个订阅者,因为没有这些,所有打开的表单都会生成它们自己的MessageBoxes。但是当一个孩子 ManagedForm 产生另一个孩子并且第二个孩子已经关闭时 - 不会显示 MessageBoxes。
我应该实施什么魔法才能只允许从第一个 ManagedForm 订阅?非常感谢您的任何想法。
编辑:建议的想法不能解决这个问题。我试图将事件更改为:
private static readonly object Locker = new object();
private static EventHandler<NotifierServiceEventArgs> _myEvent;
public static event EventHandler<NotifierServiceEventArgs> OnOk
{
add
{
if (_myEvent == null || _myEvent.GetInvocationList().All(_ => _.Method.DeclaringType != value.Method.DeclaringType))
{
_myEvent += value;
}
}
remove
{
_myEvent -= value;
}
}
然后我打开一个模态子窗体并创建一个事件已被NotifierService 触发的情况。一个MessageBox 已生成并显示(没关系)。之后,我从一开始就打开了另一个模态表单,并创建了另一个触发另一个事件的情况。一个MessageBox 已生成并显示(也可以)。现在我正在关闭第二种形式并制作触发事件所需的情况。没有显示MessageBoxes(但在主窗体的状态条中事件消息已正确显示,因此与我的第一个实现相比没有任何改变)。
我应该更改remove 子句中的某些内容吗?我不需要只有一个订阅者,我需要每个订阅者应该是不同的类型。对不起,如果英语不好。
【问题讨论】:
-
你能添加一个布尔标志来表示第一次订阅吗?
-
@rawnald-gregory-erickson 谢谢,但不,我不能。这是个坏主意,因为当我的主表单订阅一个事件时——标志将变为
true,因此所有其他子表单都将被取消资格。而且有很多事件,不仅仅是一个。 -
@xtnd8:根据页面msdn.microsoft.com/en-us/library/8edha89s.aspx += 运算符不能重载,但它使用 + 可以重载。也许你可以重载 + 运算符:)?
-
@P.K. : 不可能(看here)。
-
@xtnd: 所以你不能重载等于 x = x+y 的 x+=y 并将其重载到 x = 0 + y?只是想:)
标签: c# .net winforms events delegates