Raise an Event of a Class from a Different Class in C#

Raise an event of a class from a different class in C#

This is not possible, Events can only be risen from inside the class. If you could do that, it would defeat the purpose of events (being able to rise status changes from inside the class). I think you are misunderstanding the function of events - an event is defined inside a class and others can subscribe to it by doing

obj.AfterSearch += handler; (where handler is a method according to the signature of AfterSearch). One is able to subscribe to the event from the outside just fine, but it can only be risen from inside the class defining it.

How to use an event between 2 classes

The event handlers are associated with an instance of the class (SimpleEventSender in this case).

You're creating multiple SimpleEventSender instances:

  • One in the Form1 constructor, where you subscribe to the event
  • One every 5 iterations of CountStart, where you raise the event - but on a new instance of SimpleEventSender, that doesn't have any subscribers

You almost certainly want to use a single instance of SimpleEventSender, e.g.

// The form now retains a reference to the instance of SimpleEventSender
public partial class Form1 : Form
{
private readonly SimpleEventSender eventSender;

public Form1()
{
eventSender = new SimpleEventSender();
eventSender.NewEvent += new_event;
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
TestClass class1 = new TestClass();
TestClass.CountStart(eventSender);
}

public void new_event(object sender, EventArgs e)
{
MessageBox.Show("multiple of 5 reached");
}
}

// TestClass now *accepts* an EventSender rather than creating its own instances
class TestClass
{
public static void CountStart(SimpleEventSender eventSender)
{
// Variable name modified to be more conventional
// A "for" loop would be more idiomatic too
int count = 0;
do
{
count++;
if (count % 5 == 0)
{
eventSender.StartEvent();
}
Thread.Sleep(1000);
} while (count < 100);
}
}

Notify when event from another class is triggered

You'll need to declare a public event on class 'B' - and have class 'A' subscribe to it:

Something like this:

class B
{
//A public event for listeners to subscribe to
public event EventHandler SomethingHappened;

private void Button_Click(object o, EventArgs s)
{
//Fire the event - notifying all subscribers
if(SomethingHappened != null)
SomethingHappened(this, null);
}
....

class A
{
//Where B is used - subscribe to it's public event
public A()
{
B objectToSubscribeTo = new B();
objectToSubscribeTo.SomethingHappened += HandleSomethingHappening;
}

public void HandleSomethingHappening(object sender, EventArgs e)
{
//Do something here
}

....

Calling event of another class

Well, the typical solution is to put eSomeEvent invocation into the EventManager class

public class EventManager
{
public delegate void TempDelegate();
public static event TempDelegate eSomeEvent;

// Not thread safe as well as your code
// May be internal, not public is better (if SomeOtherClass is in the same namespace)
public static void PerformSomeEvent() {
if (!Object.ReferenceEquals(null, eSomeEvent))
eSomeEvent(); // <- You can do it here
}
}

public class SomeOtherClass
{
//doing some stuff, then:
EventManager.PerformSomeEvent();
}

Need event handler in another class

You need to bubble the event up and out of the VCtrlDetails class. You could do so by creating an event within the VCtrlDetails class and allowing your UcResult_Details class to subscribe to it.

public partial class VCtrlDetails : UserControl
{
public event EventHandler<bool> EnableEditTemplateButton;
public event EventHandler<EventArgs> DetailsGridSelectionChanged;

private void InitializeComponent()
{
private System.Windows.Forms.DataGrid detailsGrid;
this.detailsGrid.SelectionChanged += new
System.EventHandler(this.detailsGrid_SelectionChanged);

}

private void detailsGrid_SelectionChanged(object sender, EventArgs e)
{
EnableEditButton?.Invoke(this, IsApproved());

//Raise your custom event
DetailsGridSelectionChanged?.Invoke(this, e);
}

public bool IsApproved()
{
}
}

public partial class UcResult_Details : UserControl
{
private readonly VCtrlDetails vCtrlDetails;

UcResult_Details()
{
//Need to subscribe to vCtrlDetails' grid selection changed event here in this ctor
this.vCtrlDetails.DetailsGridSelectionChanged += new
EventHandler(this.vCtrlDetailsSelectionChanged);
}

private void vCtrlDetailsSelectionChanged(object sender, EventArgs e)
{
//Do whatever
}
}

C# - How to react on an Event raised in another class?

I would create an event in the Service which will be raised when the FileSystemWatcher is raised. The Service should wrap the FileSystemWatcher. The parent of both objects will call a method on the UserControl.

For example: (PSEUDO)


class MyProgram
{
Service svc;
UserControl ctrl;

public MyProgram()
{
// create the control
ctrl = new UserControl();

// create the service
svc = new Service();
svc.SaveEvent += FileChanges;

/////// you might construct something like: _(do not use both)_
svc.SaveEvent += (s, e) => ctrl.FileIsSaved(e.Filename);
}

private void FileChanges(object sender, ServiceFileChangedEventArgs e)
{
ctrl.FileIsSaved(e.Filename);
}
}

class Service
{
// FileSystemWatcher
private FileSystemWatcher _watcher;

public Service() // constructor
{
// construct it.
_watcher = new FileSystemWatcher();
_watcher.Changed += Watcher_Changed;
}

// when the file system watcher raises an event, you could pass it thru or construct a new one, whatever you need to pass to the parent object
private void Watcher_Changed(object source, FileSystemEventArgs e)
{
SaveEvent?.Invoke(this, new ServiceFileChangedEventArgs(e.FullPath)); // whatever
}

public event EventHandler<SaveEventEventArgs> SaveEvent;
}

class SaveEventEventArgs : EventArgs
{
// filename etc....
}

This is just some pseudo example code. But the important thing is, Your Program/Usercontrol should NOT depend on the FileSystemWatcher. Your Service should wrap it. So whenever you decide to change the FileSystemWatcher to (for example) a DropBoxWatcher, the rest of the program isn't broken.



Related Topics



Leave a reply



Submit