The ability to fire an event is core to mostWindows development projects. Events are useful for updating a userinterface with changed data, or causing a piece of code to run afteranother piece of code has completed. .NET has brought us a powerfulmodel for programming events. In this lesson we will write a smallapplication that will show an example of an event. This sampleillustrates the use of an event in its simplest form.
First, we will start by creating a small classthat will fire an event when a file is created or deleted. Our classwill be named FileWatch and will fire an event named OnFileChange. Thisclass will check for the existence of a file named test.txt that existsin the directory that contains the executing application (currentdirectory). If the existence of the file changes we will fire off theOnFileChange event. This also contains a method named MonitorFile thatwill continually look for the file.
When creating a class that has a consumable event, you must first declare a delegate (outside the context of the class).
public delegate void FileWatchEventHandler(object sender, EventArgs e);
Next, we will create the actual FileWatchclass. The first thing we do in our class is declare the public eventwhich we will be raising in the MonitorFile method. You will note thatthe event type is the name of the delegate that we defined earlier.
public event FileWatchEventHandler FileWatchEvent;
Now we need to create a method that we cancall which will actually raise our event. So, any time that we wish toraise our FileWatchEvent, we simply call our OnFileChange method. Whenyou raise an event in .NET you can pass data to the event consumer (thecode that is reacting to the event). In this example we are not goingto pass any data back to the consumer however we still need to passback an EventArgs object back, the object we send back will be empty.
protected virtual void OnFileChange(EventArgs e)
{
if (FileWatchEvent != null)
{
// Invokes the delegates.
FileWatchEvent(this, e);
}
}
The last thing we need to do in our FileWatchclass is to create a method that will perform a bit of work and raiseour event at the appropriate time. The MonitorFile method willconstantly check the current directory for the file named ?test.txt?.If the existence of this file changes (IE: the file gets created ordeleted) then we raise our event by calling the method OnFileChange.
public void MonitorFile()
{
bool bCurrentStatus;
while(true)
{
bCurrentStatus = File.Exists("test.txt");
if ( bCurrentStatus != _bLastStatus )
{
_bLastStatus = bCurrentStatus;
OnFileChange( EventArgs.Empty );
}
//Sleep for a little
Thread.Sleep(250);
}
}
Please refer to our completed code below in figure 1.
Figure 1
/* Example 1: Fire a simple event, do not pass values to the event consumer. */
using System;
using System.Threading; // For the sleep functionality.
using System.IO; // For the File class.
namespace Sample.Event
{
public delegate void FileWatchEventHandler(object sender, EventArgs e);
public class FileWatch
{
private bool _bLastStatus = false;
public FileWatch()
{
//
// TODO: Add constructor logic here
//
}
public event FileWatchEventHandler FileWatchEvent;
protected virtual void OnFileChange(EventArgs e)
{
if (FileWatchEvent != null)
{
// Invokes the delegates.
FileWatchEvent(this, e);
}
}
public void MonitorFile()
{
bool bCurrentStatus;
while(true)
{
bCurrentStatus = File.Exists("test.txt");
if ( bCurrentStatus != _bLastStatus )
{
_bLastStatus = bCurrentStatus;
OnFileChange( EventArgs.Empty );
}
//Sleep for a little
Thread.Sleep(250);
}
}
}
}
In the next section we will consume our event.In order to do this, we will create a small windows application tostart our file monitor and react to the event. For simplicity we willsimply indicate that something has changed. In the sample I invoke theMonitorFile method in its own thread. This was done so that the filecan be monitored without blocking the form?s UI from being updated.
We compile the FileWatch class and beginwriting a windows form application. Add a reference to theFileWatch.dll and import the namespace by using the following code:
using Sample.Event;
Inside the windows form class we add areference to the FileWatch class. We will use this reference to wire upthe event to a method in the windows form class. This local method willupdate the form when the event is raised.
public class frmMain : System.Windows.Forms.Form
{
private Sample.Event.FileWatch FileWatchEventSource;
Next we will wire up the event to a localmethod in the frmMain class. We wire up the event by using thefollowing code in the class constructor:
public frmMain()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// Create an instance of the FileWatch class so we can consume it's event.
FileWatchEventSource = new Sample.Event.FileWatch();
// "Wire up" the FileWatch event so we can respond to it if it should fire.
We wire up the FileWatchEvent to the local method named OnFileChange with the following line of code:
FileWatchEventSource.FileWatchEvent += new Sample.Event.FileWatchEventHandler( OnFileChange );
Once you wire up the event to a method thatwill handle the event, you need to run the code that will start theMonitorFile method in the FileWatch class. In this sample I decided tostart the MonitorFile method in its own thread. I did this so thatwhile the MonitorFile method is running the form can sit idle until theevent we created is raised. See the code section below, it spawns theMonitorFile method in a new thread.
//Make a thread to run the monitor method.
thrd = new Thread(new ThreadStart(FileWatchEventSource.MonitorFile));
//Start the thread.
thrd.Start();
The only thing left to do now is to actuallyreact to the event when it is raised. In order to do this we need towrite a method that will handle the event in the windows form class. Wealready wired up the FileWatchEvent to a local method namedOnFileChange, so let's create that method so we can use the event.
Place a listbox control on the form and nameit listBox. When the event is raised, we will add a line to the listboxindicating that the file has changed.
private void OnFileChange( object Sender, EventArgs e )
{
// e will be empty in this sample because we are not passing args.
listBox.Items.Add( DateTime.Now.ToString() + ": file changed." );
}
When you consume an event, the EventHandlerwill pass a reference to the sender and an EventArgs class. TheEventArgs class is used to pass information from the event source tothe event consu
mer. In
this sample, we are not passing any informationto the event consumer and will not use the EventArgs class in thismethod. Instead, we will simply react to the event by inserting a lineof text into a listbox.
Download Lesson 1