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 ofSimpleEventSender
, 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
Why C# Won't Allow Field Initializer with Non-Static Fields
Simulating Keyboard with Sendinput API in Directinput Applications
Change File Extension Using C#
How to Write a Transaction to Cover Moving a File and Inserting Record in Database
Fill Panel with Gradient in Three Colors
Net Core: Execute All Dependency Injection in Xunit Test for Appservice, Repository, etc
How to Programmatically Change Printer Settings with the Webbrowser Control
How to Programmatically Change Printer Settings with the Webbrowser Control
Get Just the Domain Name from a Url
How to Read Image Pixels' Values as Rgb into 2D Array
Add Timer to a Windows Forms Application
How to Secure Passwords Stored Inside Web.Config
How to Asynchronously Read the Standard Output Stream and Standard Error Stream at Once