public class EventBroker
{
Dictionary<string, List<Delegate>> _subscriptions =
new Dictionary<string, List<Delegate>>();
public void Register(string eventId, Delegate method)
{
//associate an event handler for an eventId
List<Delegate> delegates = null;
if (!_subscriptions.TryGetValue(eventId, out delegates))
{
delegates = new List<Delegate>();
_subscriptions[eventId] = delegates;
}
delegates.Add(method);
}
public void Unregister(string eventId, Delegate method)
{
//unassociate a specific event handler method for the eventId
List<Delegate> delegates = null;
if (_subscriptions.TryGetValue(eventId, out delegates))
{
delegates.Remove(method);
if (delegates.Count == 0)
{
_subscriptions.Remove(eventId);
}
}
}
public void OnEvent(string eventId, params object[] args)
{
//call all event handlers for the given eventId
List<Delegate> delegates = null;
if (_subscriptions.TryGetValue(eventId, out delegates))
{
foreach (Delegate del in delegates)
{
if (del.Method != null)
{
if (del.Target != null)
{
del.DynamicInvoke(args);
}
}
}
}
}
}
public partial class Form1 : Form
{
//a single event broker to tie all controls together
EventBroker _broker = new EventBroker();
public Form1()
{
InitializeComponent();
myControl11.SetEventBroker(_broker);
myControl21.SetEventBroker(_broker);
myControl31.SetEventBroker(_broker);
}
}
public partial class MyControl1 : UserControl
{
EventBroker _broker;
public MyControl1()
{
InitializeComponent();
}
public void SetEventBroker(EventBroker broker)
{
_broker = broker;
}
//when user clicks button, fire the global event
private void buttonTrigger_Click(object sender, EventArgs e)
{
if (_broker != null)
{
_broker.OnEvent("MyEvent");
}
}
}
public partial class MyControl2 : UserControl
{
EventBroker _broker;
public MyControl2()
{
InitializeComponent();
}
public void SetEventBroker(EventBroker broker)
{
_broker = broker;
_broker.Register("MyEvent", new MethodInvoker(OnMyEvent));
}
private void OnMyEvent()
{
labelResult.Text = "Event triggered!";
}
}
//MyControl3 is the same as MyControl2
Note
This method is
most appropriate for global events that you need to communicate across
the entire application, and passing objects around complicated code
hierarchies just to listen for events is not worth the headache and
maintenance problems that are entailed. For more local events, you
should definitely just use the normal .NET event pattern.