With traditional programming languages (often referred to as procedural languages), the program itself fully dictates what code is executed as well as when it's executed. When you start such a program, the first line of code in the program executes, and the code continues to execute in a completely predetermined path. The execution of code might branch and loop on occasion, but the execution path is wholly determined by the program. This often means that such a program is restricted in how it can respond to the user. For example, the program might expect text to be entered into controls on the screen in a predetermined order. This is unlike a Windows application in which a user can interact with different parts of the interfaceoften in any order the user chooses. Visual C# 2005 incorporates an event-driven programming model. Event-driven applications aren't bound by the constraints of procedural programs. Instead of the top-down approach of procedural languages, event-driven programs have logical sections of code placed within events. There's no predetermined order in which events occur; the user often has complete control over what code is executed in an event-driven program by interactively triggering specific events, such as by clicking a button. An event, along with the code it contains, is called an event procedure. Triggering EventsIn Hour 3, you learned that a method is simply a function of an object. Events, in a sense, are really a special kind of method used by an object to signal state changes that might be useful to clients (code using the object). In fact, the Visual C# 2005 documentation refers to events as methods quite frequently (something that will no doubt cause confusion in new programmers). Events are methods that can be called in special waysusually by the user interacting with something on a form or by Windows itselfrather than being called from a statement in your code. There are many types of events and many ways to trigger those events. You've already seen how a user can trigger the event of a button by clicking it. User interaction isn't the only thing that can trigger an event; an event can be triggered in one of the following four ways:
Events Triggered Through User InteractionThe most common way an event is triggered is by a user interacting with a program. Every form, and almost every control you can place on a form, has a set of events specific to its object type. The Button control, for example, has a number of events, including the Click event that you've already used in previous hours. When the user clicks a button, the button's Click event is triggered and then the code within the Click event executes. The Textbox control enables users to enter information using the keyboard, and it also has a set of events. The Textbox control has some of the same types of events as the Button control, such as a Click event, but the Textbox control also has events not supported by the Button control, such as the MultilineChanged event. The MultilineChanged event occurs when the Multiline property of the text box changes. Because a user can't enter text into a Button control, it doesn't have a Multiline property and therefore no MultilineChanged event. Every object that supports events supports a unique set of events. Each type of event has its own behavior, and it's important to understand the events you work with. The TextChanged event, for example, exhibits a behavior that might not be intuitive to a new developer because the event fires each time the contents of the text box change. Consider what would happen if you were to type the following sentence into an empty text box in a project you created: Visual C# 2005 is very cool! Although it's easy to think that the TextChanged event fires only when you commit your entry, such as by leaving the text box or pressing Enter, this isn't how it works. Instead, the TextChanged event would be triggered 28 timesonce for each character typedbecause each time you enter a new character, the contents of the text box is changed. Again, it's important to learn the nuances and the exact behavior of the events you're using. If you use events without fully understanding how they work, your program might exhibit unusual (which usually means undesirable) results. By the Way Triggering events (which are just a type of procedure) using Visual C# code is discussed in detail in Hour 10, "Creating and Calling Methods." Events Triggered by an ObjectSometimes an object triggers its own events. The most common example of this is the Timer control's Tick event. The Timer control is a non-visual control like the common dialog control; it doesn't appear on a form when the program is running, it appears at design time in the space reserved for non-visual controls. The Timer control's sole purpose is to trigger its Tick event at an interval specified in its Interval property. By setting the Timer control's Interval property, you control the interval (in milliseconds) at which the Timer event executes. After firing its Timer event, a Timer control resets itself and fires its Timer event again when the interval has passed. This occurs until the interval is changed, the Timer control is disabled, or the Timer control's form is unloaded. A common use of timers is to create a clock on a form. You can display the time in a label and update it at regular intervals by placing the code to display the current time in the Timer event. You'll create a project with a Timer control in Hour 8, "Using Advanced Controls." Events Triggered by the Operating SystemThe third way an event can be triggered is by Windows itself. Often, you might not even realize these events exist. For example, when a form is fully or partially obstructed by another window, the program needs to know when the offending window is resized or moved so that it can repaint the area of the window that's hidden. Windows and Visual C# work together in this respect. When the obstructing window is moved or resized, Windows tells Visual C# to repaint the form, which Visual C# does. This also causes Visual C# to raise the form's Paint event. You can place code into the Paint event to create a custom display for the form, such as drawing shapes on the form using a Graphics object. By doing so, your custom drawing code executes every time the form repaints itself. Avoiding Recursive EventsYou must ensure that you never create code where an event can endlessly trigger itself. An event that continuously triggers itself is called a recursive event. To illustrate a situation that causes a recursive event, think of the Textbox control's TextChanged event discussed earlier. The TextChanged event fires every time the text within the text box changes. Placing code into the TextChanged event that alters the text within the text box causes the Change event to be fired again, which could result in an endless loop. Recursive events terminate when Windows returns a StackOverflow exception (see Figure 4.1), indicating that Windows no longer has the resources to follow the recursion. Figure 4.1. When you receive a StackOverflow exception, you should look for a recursive event as the culprit.Recursive behavior can occur with more than one event in the loop. For example, if Event A triggers Event B, which in turn triggers Event A, you can have infinite looping of the two events. Recursive behavior can take place among a sequence of many events, not just one or two. By the Way Uses for recursive procedures actually exist, such as when writing complex math functions. For instance, recursive events are often used to compute factorials. However, when you purposely create a recursive event, you must ensure that the recursion isn't infinite. Accessing an Object's EventsAccessing an object's events is simple, and if you've been following the examples in this book, you've already accessed a number of objects' default events. To access an object's events, you double-click the object in Form Design view. You're now going to create a project to get a feel for working with events. Start Visual C# 2005, create a new Windows Application project titled View Events, and then follow these steps:
Currently, you're viewing the MouseDown event for the picTest object. The cursor is placed within the MouseDown event procedure, ready for you to enter code. The code statement above the cursor is the event declaration. An event declaration is a statement that defines the structure of an event. Notice that this event declaration contains the name of the object, an underscore character (_), and then the event name. Following the event name is a set of parentheses. The items within the parentheses are called parameters, which are the topic of the next section. This is the standard declaration structure for an event procedure. When you double-click an event in the Events list, Visual C# creates a new event procedure for that event. The full event declaration and event structure is shown here: private void picTest_MouseDown(object sender, MouseEventArgs e) { } By the Way The open and closed braces denote the beginning and ending of the procedure; all code for the procedure needs to be placed between these two braces. Working with Event ParametersAs mentioned previously, the items within the parentheses of an event declaration are called parameters. An event parameter is a variable that's created and assigned a value by Visual C#. These parameter variables are used to get, and sometimes set, relevant information within the event. This data may be text, a number, an objectalmost anything. Multiple parameters within an event procedure are always separated by commas. As you can see, the MouseDown event has two parameters. When the event procedure is triggered, Visual C# automatically creates the parameter variables and assigns them values for use in this single execution of the event procedure; the next time the event procedure occurs, the values in the parameters are reset. You use the values in the parameters to make decisions or perform operations in your code. The MouseDown event of a form has the following parameters: object sender and MouseEventArgs e The first piece of text in a parameter indicates the type of data the parameter contains, and the second piece of text is the name of the variable containing the data. The first parameter, sender, holds a generic object. Object parameters can be any type of object supported by Visual C#. It's not critical that you understand data types right now, just be aware that different parameter variables contain different types of information. Some contain text, others contain numbers, and still others (many others) contain objects. In the case of the sender parameter, it will always hold a reference to the control causing the event. The e parameter of the MouseDown event, on the other hand, is where the real action is. The e parameter also holds an object, but in this case the object is of type MouseEventArgs. This object has properties that relate to the MouseDown event. To see them, type in the following code, but don't press anything after entering the dot (period): e. When you press the period, you'll get a drop-down list showing you the members (properties and methods) of the e object (see Figure 4.4). Using the e object, you can determine a number of things about the occurrence of the MouseDown event. I've listed some of the more interesting items in Table 4.1. Figure 4.4. IntelliSense drop-down lists alleviate the need for memorizing the make up of hundreds of objects.
By the Way Each time the event occurs, the parameters are initialized by Visual C# so that they always reflect the current occurrence of the event. Each event has parameters specific to it. For instance, the TextChanged event returns parameters that are different from the MouseDown event. As you work with eventsand you'll work with a lot of eventsyou'll quickly become familiar with the parameters of each event type. You'll learn how to create parameters for your own functions and procedures in Hour 10. Deleting an Event HandlerDeleting an event handler involves more than just deleting the event procedure. When you add a new event handler to a class, Visual C# automatically creates the event procedure for you and positions you to enter code within the event. However, Visual C# does a little bit more "under the hood" to hook the event procedure to the control. It does this by creating a code statement in the hidden code of the class. Ordinarily, you don't have to worry about this statement. However, when you delete an event procedure, Visual C# doesn't automatically delete the hidden code statement, and your code won't compile. The easiest way to correct this is simply to run the project; when Visual C# encounters the error, it will show you the offending statement, which you can delete. Try this now:
Whenever you delete an event procedure, you'll have to delete the corresponding statement that links the procedure to its object before the code will run. Did you Know? Now that you've learned the process of deleting an event handler, here's the quickest and easiest way: View the object in design view and click the Events button on the Properties window to view the object's events. Then, highlight the event name in the Properties window and press the Delete key. This will leave event code that will remain in the class until you delete it, but it will no longer be used. |