I have Windows Forms application with one main form (derived from base Form
). Other modal forms that could be opened there are derived from my class ManagedForm
, which is also derived from Form
.
Also I have a static notifier service which fires some events like this:
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
}
So in some places of code these events could be fired like:
NotifierService.NotifyExclamation("Fail!");
In the main form there is StatusStrip
control used for notification purposes, and due to main form has subscribtion to these events -- their messages will be shown in the status strip.
BUT!, as I've said earlier, user may open other forms, and these forms could produce others and so on... (they are derived from one class ManagedForm
which will be subscribed to NotifierService
as soon as it has been created).
In these forms there is another logic how to notify user -- they need to show MessageBox
es with messages. As you can see, I've added some magic in event accessors to allow only one subscriber of any type, because w/o this all opened forms will generate their own MessageBox
es. But when one child ManagedForm
has produced another and the second has been closed -- no MessageBox
es will be shown.
What magic should I implement to allow subscription from only first ManagedForm
? Many thanks for any ideas.
EDIT: Suggested ideas doesn't solve this issue. I've tried to change event to this:
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;
}
}
Then I've open one modal child form and create a situation in which event has been fired by NotifierService
. One MessageBox
has been generated and shown (that's OK). Afterwards I've opened another modal form from first and create another situation in which another event has been fired. One MessageBox
has been generated and shown (that's also OK). Now I'm closing second form and making a situation needed to fire event. No MessageBox
es has been shown (but in the status strip of the main form message of event has been shown correctly, so nothing has been changed from my first implementation).
Should I change something in remove
clause? I do not need that only one subscriber should be, I need that each of the subscribers should be of distinct types. Sorry If bad English.