Tuesday, September 14, 2004
Control Events
Controls can have events that are associated with them. Suppose that we had a server control that contained a single button. The button click event could perform some processing directly, or the event could call a function in another client via an exposed public event. If we have a number of different pages that contain the server control on them, each page could hook a function to the event defined in the button. When the button click event is fired, the hook function on the page is called. The page can now determine what happens in response to a click event that occurred on the button within an embedded server control. It is the page's responsibility to wire the button click event to the hook function. Note that the server control (or the button within the control) has no knowledge of what client is consuming it. Each page within the application can determine the behavior of the control event via the exposed hook function on the page. Suppose we had the following in the ascx file for the control: <table width="100%"> <TR> <td align="right"> <asp:Button id="btnProceed" runat="server" Text="Proceed"></asp:Button> </td> <td align="left"> <asp:Button id="btnCancel" runat="server" Text="Cancel"></asp:Button> </td> </TR> </table> In the code behind for the control we would define two EventHandlers, one for each button: public event EventHandler Proceed; public event EventHandler Cancel; The button events would then forward to the hook method associated with the Proceed, or Cancel event objects. private void btnProceed_Click(object sender, System.EventArgs e) { Proceed(this, e); } private void btnCancel_Click(object sender, System.EventArgs e) { Cancel(this, e); } The page that contains the control, sets the OnProceed and OnCancel events on the control to the hook functions in the code-behind of the page: <%@ Register TagPrefix="ctrl" TagName="Buttons" Src="Buttons.ascx" %> ... <ctrl:buttons id="NavigateButtons" runat="server" OnProceed="Page_Proceed" OnCancel="Page_Cancel"></ctrl:buttons> The code behind of the page contains the hook functions Page_Proceed and Page_Cancel. Note that the hook functions are protected. The generated class that derives from the code behind will need to access the two hook functions, so they are declared with protected visibility. protected void Page_Proceed(object sender, System.EventArgs e) { // do something for proceed } protected void Page_Cancel(object sender, System.EventArgs e) { // do something for cancel } When the aspx page is parsed and the dynamic class is generated, the control properties OnProceed and OnCancel are translated into the following code (in the generated page class): NavigateButtons.Proceed += new EventHandler(this.Page_Proceed); NavigateButtons.Cancel += new EventHandler(this.Page_Cancel); When the Button1_Click event in the control fires, the Page_Proceed method is called in the page. Each page can now define hook methods that should be called when the button click events on the contained control are fired. Each page defines the hook functions, and the control tag in the .aspx page is modified to associate the hook methods with events in the control:
// page A <ctrl:buttons id="NavigateButtons" runat="server" OnProceed="PageA_Proceed" OnCancel="PageA_Cancel"></ctrl:buttons> // page B <ctrl:buttons id="NavigateButtons" runat="server" OnProceed="PageB_Proceed" OnCancel="PageB_Cancel"></ctrl:buttons> The functions within each page (PageA_Proceed, PageB_Proceed) do not have to be named uniquely. Both pages could contain a Page_Proceed and Page_Cancel hook functions, the only difference being that the Page_Proceed and Page_Cancel in each page would perform different operations. |
|