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%">
<td align="right">
<asp:Button id="btnProceed" runat="server" Text="Proceed"></asp:Button>
<td align="left">
<asp:Button id="btnCancel" runat="server" Text="Cancel"></asp:Button>

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:

  • Add the EventHandler declarations in the control

  • Add the hook functions in the parent page that should be called when the event in the control is triggered

  • Add the server control tag to the .aspx file associated with the page

  • Add the On... attributes to the server control tag and set the attributes to the appropriate hook function in the page. Make sure that the attribute is named the same as the declared event in the control, prefixed by On. So if the event field in the control is Proceed, the attribute on the control in the .aspx page should be in the format OnProceed="hook function name in page"
Now each page can define their own hook functions for the Proceed and Cancel events exposed by 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.

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?