C# 2.0: The Complete Reference (Complete Reference Series)

Events are frequently used in message-based environments, such as Windows. In such an environment, a program simply waits until it receives a message, and then it takes the appropriate action. Such an architecture is well suited for C#-style event handling because it is possible to create event handlers for various messages and then to simply invoke a handler when a message is received. For example, the left-button mouse click message could be tied to an event called LButtonClick. When a left-button click is received, a method called OnLButtonClick( ) can be called, and all registered handlers will be notified.

Although developing a Windows program that demonstrates this approach is beyond the scope of this chapter, it is possible to give an idea of how such an approach would work. The following program creates an event handler that processes keystrokes. The event is called KeyPress, and each time a key is pressed, the event is fired by calling OnKeyPress( ).

// A keypress event example. using System; // Derive a custom EventArgs class that holds the key. class KeyEventArgs : EventArgs { public char ch; } // Declare a delegate for an event. delegate void KeyHandler(object source, KeyEventArgs arg); // Declare a keypress event class. class KeyEvent { public event KeyHandler KeyPress; // This is called when a key is pressed. public void OnKeyPress(char key) { KeyEventArgs k = new KeyEventArgs(); if(KeyPress != null) { k.ch = key; KeyPress(this, k); } } } // Demonstrate KeyEvent. class KeyEventDemo { public static void Main() { KeyEvent kevt = new KeyEvent(); ConsoleKeyInfo key; int count = 0; // Use anonymous method to display the keypress. kevt.KeyPress += delegate(object source, KeyEventArgs arg) { Console.WriteLine(" Received keystroke: " + arg.ch); }; // Use an anonymous method to count keypresses. kevt.KeyPress += delegate (object source, KeyEventArgs arg) { count++; // count is an outer variable }; Console.WriteLine("Enter some characters. " + "Enter a period to stop."); do { key = Console.ReadKey(); kevt.OnKeyPress(key.KeyChar); } while(key.KeyChar != '.'); Console.WriteLine(count + " keys pressed."); } }

Here is a sample run:

Enter some characters. Enter a period to stop. t Received keystroke: t e Received keystroke: e s Received keystroke: s t Received keystroke: t . Received keystroke: . 5 keys pressed.

The program begins by deriving a class from EventArgs called KeyEventArgs, which is used to pass a keystroke to an event handler. Next, a delegate called KeyHandler defines the event handler for keystroke events. The class KeyEvent encapsulates the keypress event. It defines the event KeyPress.

In Main( ), a KeyEvent object called kevt is created. Next, an anonymous event handler is added to kevt.KeyPress that displays each key as it is entered, as shown here:

// Use anonymous method to display the keypress. kevt.KeyPress += delegate(object source, KeyEventArgs arg) { Console.WriteLine(" Received keystroke: " + arg.ch); };

Next, another anonymous handler is added to kevt.KeyPress by the following code. It counts the number of keypresses.

// Use an anonymous method to count keypresses. kevt.KeyPress += delegate (object source, KeyEventArgs arg) { count++; // count is an outer variable };

Notice that count is a local variable declared in Main( ) that is initialized to zero.

Next, a loop is started that calls kevt.OnKeyPress( ) when a key is pressed. This causes the registered event handlers to be notified. When the loop ends, the number of keypresses is displayed. Although quite simple, this example illustrates the essence of event handling. The same basic approach will be used for other event handling situations. Of course, in some cases, anonymous event handlers will not be appropriate, and “normal” event handler methods will need to be employed.

Категории