I have a class, EventContainer.cs, which contains an event, say:
public event EventHandler AfterSearch;
I have another class, EventRaiser.c
There is good way to do this. Every event in C# has a delegate that specifies the sign of methods for that event. Define a field in your external class with type of your event delegate. get the the reference of that field in the constructor of external class and save it. In main class of your event, send the reference of event for delegate of external class. Now you can easily call the delegate in your external class.
public delegate void MyEventHandler(object Sender, EventArgs Args);
public class MyMain
{
public event MyEventHandler MyEvent;
...
new MyExternal(this.MyEvent);
...
}
public MyExternal
{
private MyEventHandler MyEvent;
public MyExternal(MyEventHandler MyEvent)
{
this.MyEvent = MyEvent;
}
...
this.MyEvent(..., ...);
...
}
It looks like you're using the Delegate pattern. In this case, the AfterSearch
event should be defined on the EventRaiser
class, and the EventContainer
class should consume the event:
In EventRaiser.cs
public event EventHandler BeforeSearch;
public event EventHandler AfterSearch;
public void ExecuteSearch(...)
{
if (this.BeforeSearch != null)
this.BeforeSearch();
// Do search
if (this.AfterSearch != null)
this.AfterSearch();
}
In EventContainer.cs
public EventContainer(...)
{
EventRaiser er = new EventRaiser();
er.AfterSearch += this.OnAfterSearch;
}
public void OnAfterSearch()
{
// Handle AfterSearch event
}
I took a slightly different approach in solving this problem. My solution consisted of a winform front end, a main Class Library (DLL) and within that dll, a secondary working class:
WinForm |------> PickGen Library |---------> Allocations class
What I decided to do is to create events in the main dll (PickGen) that the Allocations class could call, then those event methods would called the events within the UI.
So, allocations raises an event in PickGen which takes the parameter values and raises the event in the form. From a code standpoint, this is in the lowest class:
public delegate void AllocationService_RaiseAllocLog(string orderNumber, string message, bool logToDatabase);
public delegate void AllocationService_RaiseAllocErrorLog(string orderNumber, string message, bool logToDatabase);
public class AllocationService { ...
public event AllocationService_RaiseAllocLog RaiseAllocLog;
public event AllocationService_RaiseAllocErrorLog RaiseAllocErrorLog;
then later in the subclass code:
RaiseAllocErrorLog(SOHNUM_0, ShipmentGenerated + ": Allocated line QTY was: " + allocatedline.QTY_0 + ", Delivered was: " + QTY_0 + ". Problem batch.", false);
In the main DLL Class library I have these two event methods:
private void PickGenLibrary_RaiseAllocLog(string orderNumber, string message, bool updateDB)
{
RaiseLog(orderNumber, message, false);
}
private void PickGenLibrary_RaiseAllocErrorLog(string orderNumber, string message, bool updateDB)
{
RaiseErrorLog(orderNumber, message, false);
}
and I make the connection here when I create the allocation object:
AllocationService allsvc = new AllocationService(PickResult);
allsvc.RaiseAllocLog += new AllocationService_RaiseAllocLog(PickGenLibrary_RaiseAllocLog);
allsvc.RaiseAllocErrorLog += new AllocationService_RaiseAllocErrorLog(PickGenLibrary_RaiseAllocErrorLog);
and I also then have delegates that are set up to tie the main class with the winform code:
public delegate void JPPAPickGenLibrary_RaiseLog(string orderNumber, string message, bool logToDatabase);
public delegate void JPPAPickGenLibrary_RaiseErrorLog(string orderNumber, string message, bool logToDatabase);
It may not be the most elegant way to do it, but in the end, it does work and without being too obscure.
The raising class has to get a fresh copy of the EventHandler
.
One possible solution below.
using System;
namespace ConsoleApplication1
{
class Program
{
class HasEvent
{
public event EventHandler OnEnvent;
EventInvoker myInvoker;
public HasEvent()
{
myInvoker = new EventInvoker(this, () => OnEnvent);
}
public void MyInvokerRaising() {
myInvoker.Raise();
}
}
class EventInvoker
{
private Func<EventHandler> GetEventHandler;
private object sender;
public EventInvoker(object sender, Func<EventHandler> GetEventHandler)
{
this.sender = sender;
this.GetEventHandler = GetEventHandler;
}
public void Raise()
{
if(null != GetEventHandler())
{
GetEventHandler()(sender, new EventArgs());
}
}
}
static void Main(string[] args)
{
HasEvent h = new HasEvent();
h.OnEnvent += H_OnEnvent;
h.MyInvokerRaising();
}
private static void H_OnEnvent(object sender, EventArgs e)
{
Console.WriteLine("FIRED");
}
}
}
Very simple example. i like to do it this way using EventHandler.
class Program
{
static void Main(string[] args)
{
MyExtension ext = new MyExtension();
ext.MyEvent += ext_MyEvent;
ext.Dosomething();
Console.ReadLine();
}
static void ext_MyEvent(object sender, int num)
{
Console.WriteLine("Event fired.... "+num);
}
}
public class MyExtension
{
public event EventHandler<int> MyEvent;
public void Dosomething()
{
int no = 1;
if (MyEvent != null)
MyEvent(this, ++no);
}
}
}
Not a good programming but if you want to do that any way you can do something like this
class Program
{
static void Main(string[] args)
{
Extension ext = new Extension();
ext.MyEvent += ext_MyEvent;
ext.Dosomething();
}
static void ext_MyEvent(int num)
{
Console.WriteLine(num);
}
}
public class Extension
{
public delegate void MyEventHandler(int num);
public event MyEventHandler MyEvent;
public void Dosomething()
{
int no = 0;
while(true){
if(MyEvent!=null){
MyEvent(++no);
}
}
}
}