In the previous article Article We have discussed the basic theory about creating composite controls, and mastered the rendering method of composite controls through a typical application. This article will continue to explain how to create a composite control, focusing on how to implement events for the composite control.
Introduction to event processing of composite controls
Speaking of event processing for custom controls, this has been explained in the previous series. As we can see from the previous article, the core of the control event is to define the event property structure and event processing program. However, these contents are the basis for building all custom server controls. By relying solely on these methods, composite control events cannot be implemented. Because composite controls contain child controls, the event processing of composite controls becomes complicated. Obviously, the biggest problem to be faced during the event Implementation of composite controls is that developers are not allowed to directly access sub-Controls (although they can be accessed through the controls set, but it destroysProgramIs not allowed.) If the sub-control event cannot be triggered as a top-level event, the sub-control event cannot be processed. To put it simply, it is how to implement the event upload of the Child control. The so-called event upload refers to exposing the sub-control event as a top-level event, so that the parent control can check the event and execute the relevant event processing program according to the definition.
From the above content, we can see that the event processing of the composite control is mainly the process of uploading sub-control events. The following describes two common event upload implementation methods: the inclusion method and the bubble method. The two methods have different implementation mechanisms. However, the same function is completed. In the following section, we will explain it through a combination of theory and examples.
Inclusion Method
The core of the inclusion method is to upload the sub-control events by calling the top-level event handler of the Composite Control in the event handler of the sub-control. When a subcontrol event is triggered, the subcontrol event handler automatically calls the relevant top-level event handler.
The key steps of the Inclusion Method are as follows:
· In the createchildcontrols method, add an event handler for the Child control.
· Define the top-level event and its event handler oneventname.
· Oneventname is called in the event handler of the Child control.
· Define the event property structure.
The preceding steps are similar to the methods used to implement controls described in the previous article. The key is to add an event handler for the Child control in the createchildcontrols method. For readers to better understand the inclusion method, the following describes an example of using the inclusion method as a composite control to implement events.
First, create a composite control composed of text boxes and buttons using the composite control rendering method described in the previous article. Then, use the inclusion method described above, upload the Click Event of the button as the top-level event submit. The following listsSource code.
Using system; Using system. Web. UI; Using system. Web. UI. webcontrols; Using system. componentmodel; Using system. componentmodel. design; Namespace webcontrollibrary { Public class compositeevent: compositecontrol { // Declare Variables Private button _ button; Private textbox _ textbox; Private Static readonly object eventsubmitkey = new object (); // Define the attribute buttontext to specify the text on the button [ Bindable (true), category ("appearance"), defaultvalue (""), description ("Get or set the text displayed on the button ") ] Public String buttontext { Get { Ensurechildcontrols (); Return _ button. text; } Set { Ensurechildcontrols (); _ Button. Text = value; } } // Define the attribute text, indicating the input of the text box [ Bindable (true), category ("appearance"), defaultvalue (""), description ("Get or set text box input text ") ] Public String text { Get { Ensurechildcontrols (); Return _ textbox. text; } Set { Ensurechildcontrols (); _ Textbox. Text = value; } } // Implement the event Property Structure Public event eventhandler submit { Add { Events. addhandler (eventsubmitkey, value ); } Remove { Events. removehandler (eventsubmitkey, value ); } } // Implement onsubmit Protected virtual void onsubmit (eventargs e ){ Eventhandler submithandler = (eventhandler) events [eventsubmitkey]; If (submithandler! = NULL ){ Submithandler (this, e ); } } // Implement the event handler triggered by the submit event Private void _ button_click (Object source, eventargs e ){ Onsubmit (eventargs. Empty ); } // Override the recreatechildcontrls method of the icompositecontroldesigneraccessor Interface Protected override void recreatechildcontrols (){ Ensurechildcontrols (); } // Override the createchildcontrols method and add the child control to the composite control. Protected override void createchildcontrols (){ Controls. Clear (); _ Button = new button (); _ Textbox = new Textbox (); _ Button. ID = "BTN "; _ Button. Click + = new eventhandler (_ button_click ); This. Controls. Add (_ button ); This. Controls. Add (_ textbox ); } // Rewrite the render method to render other htmlCode Protected override void render (htmltextwriter output ){ Output. addattriter( htmltextwriterattribute. Border, "0px "); Output. addattriding (htmltextwriterattribute. cellpadding, "5px "); Output. addattriing (htmltextwriterattribute. cellspacing, "0px "); Output. renderbegintag (htmltextwritertag. Table ); Output. renderbegintag (htmltextwritertag. tr ); Output. renderbegintag (htmltextwritertag. TD ); _ Textbox. rendercontrol (output ); Output. renderendtag (); Output. renderbegintag (htmltextwritertag. TD ); _ Button. rendercontrol (output ); Output. renderendtag (); Output. renderendtag (); Output. renderendtag (); } } } |
As shown in the code above, compositeevent contains two attributes: Text and buttontext. The former is used to obtain or set the text content in the text box, and the latter is used to obtain or set the display text of the button. In addition, a submit event is also implemented in the composite control class. Important logics include:
1. In the createchildcontrols method, add the event handler _ button_click for the Child control button.
Second, like a common Custom Event, define a top-level event submit for the composite control. This includes defining the event property structure submit and the event handler onsubmit.
3. Implement the _ button_click event handler and call the onsubmit event handler of the top-level event submit.
The following is the default. aspx File Code created to test the compositeevent.
<% @ page Language = "C #" autoeventwireup = "true" codefile = "default. aspx. CS "inherits =" _ default "%> <% @ register tagprefix =" sample "assembly =" webcontrollibrary "namespace =" webcontrollibrary "%> implement event-Inclusion Method for a composite control
|
Example 1 is shown.
In the preceding application, when you click "Submit", the execution of the demo1_submit processing program is triggered, and the input content in the text box is displayed.
You need to note the internal execution process. The top-level event defined by the control is submit, and its corresponding event handler is onsubmit instead of _ button_click. _ Button_click is the click event handler of the Child control of the composite control. Because the event handler _ button_click of the child control is defined in the Code implemented by the control, after you click the button, the _ button_click, this method requires that the event handler onsubmit of the top-level event submit be called. Externally, sub-control events are exposed as top-level events.
From the above implementation process, the inclusion method uses tips on program code to implement the event upload function. Different from the bubble rule described below, it uses the event upload mechanism provided by the. NET Framework to complete the event upload of child controls.
Bubble Method
The bubble method is also called "event bubbling". Its core is to use the event upload mechanism provided by the ASP. NET 2.0 Framework. This mechanism allows child controls to spread events along their inclusive hierarchies to appropriate locations for triggering, and allows event handlers to be appended to the original controls and controls that expose the bubbling events.
For the implementation of the bubble method, the two methods used by the control base class for event upload are onbubbleevent and raisebubbleevent. Their declaration is as follows.
// Onbubbleevent method definition Protected virtual bool onbubbleevent (Object source, eventargs ARGs) {return false ;} // Raisebubbleevent method definition Protected void raisebubbleevent (Object source, eventargs ARGs ){ Control currenttarget = _ parent; While (currenttarget! = NULL ){ If (currenttarget. onbubbleevent (source, argS) {return ;} Currenttarget = currenttarget. parent; } } |
The onbubbleevent method is used to determine whether subcontrol events are passed up the composite control hierarchy. In this method, the source parameter indicates the event source, and The args parameter indicates the eventargs object that contains event data. If the sub-control event is passed up, the value is true; otherwise, the value is false. The default value is false. The raisebubbleevent method is used to allocate all event sources and their information to the control's parent level and cannot be overwritten. Although this method cannot be rewritten, the created control can be used to override the onbubbleevent method to process or trigger a bubble event.
Event bubbling of composite controls mainly involves the following two situations:
Scenario 1: The control stops event bubbling and raises and/or processes the event. To trigger an event, you must call the method to schedule the event to the listener. To trigger a bubble event, the control must override the onbubbleevent to call the oneventname method that triggers the event. The control that triggers a bubble event usually exposes the bubble event as a top-level event. The following code triggers a bubble event.
Protected override bool onbubbleevent (Object sender, eventargs e ){ Bool handled = false; If (E is commandeventargs ){ Commandeventargs Ce = (commandeventargs) E; If (Ce. commandname = "buttonclick "){ Onbuttonclick (eventargs. Empty ); Handled = true; } } Return handled; } |
Case 2: The Control performs some processing and continues to bubble the event. To achieve this, the control must override onbubbleevent and call raisebubbleevent from onbubbleevent. The following code bubbles an event after checking the type of the event parameter.
Protected override bool onbubbleevent (Object sender, eventargs e ){ If (E is commandeventargs ){ Commandeventargs Ce = (commandeventargs) E; Raisebubbleevent (this, CE ); Return true; } Return false; } |
In order to make readers better understand the bubble method, the following uses the Bubble Method to re-implement the example in the previous section. The source code of the control class is as follows, and the unchanged part is represented by the ellipsis.
Using system; Using system. Web. UI; Using system. Web. UI. webcontrols; Using system. componentmodel; Using system. componentmodel. design; Namespace webcontrollibrary { Public class compositeevent: compositecontrol { // Declare Variables Private button _ button; Private textbox _ textbox; Private Static readonly object eventsubmitkey = new object (); // Define the attribute buttontext to specify the text on the button [ Bindable (true), category ("appearance"), defaultvalue (""), description ("Get or set the text displayed on the button ") ] Public String buttontext {......} // Define the attribute text, indicating the input of the text box [ Bindable (true), category ("appearance"), defaultvalue (""), description ("Get or set text box input text ") ] Public String text {...} // implement the event Property Structure Public event eventhandler submit { Add { Events. addhandler (eventsubmitkey, value ); } Remove { Events. removehandler (eventsubmitkey, value ); } } // Implement onsubmit Protected virtual void onsubmit (eventargs e ){ Eventhandler submithandler = (eventhandler) events [eventsubmitkey]; If (submithandler! = NULL) {submithandler (this, e );} } // Delete _ button_click // Override the recreatechildcontrls method of the icompositecontroldesigneraccessor Interface Protected override void recreatechildcontrols (){......} // Override the createchildcontrols method and add the child control to the composite control. Protected override void createchildcontrols (){ Controls. Clear (); _ Button = new button (); _ Textbox = new Textbox (); _ Button. ID = "BTN "; _ Button. commandname = "Submit "; This. Controls. Add (_ button ); This. Controls. Add (_ textbox ); } // Override the onbubbleevent method and execute event bubbling Protected override bool onbubbleevent (Object source, eventargs e ){ Bool handled = false; If (E is commandeventargs ){ Commandeventargs Ce = (commandeventargs) E; If (Ce. commandname = "Submit "){ Onsubmit (eventargs. Empty ); Handled = true; } } Return handled; } // Rewrite the render method to render other HTML code in the control Protected override void render (htmltextwriter output ){......} } } |
In this example, the compositeevent class and the compositeevent class in the preceding section implement the same function. There is no difference between the two classes in terms of control rendering, and the difference is mainly manifested in the event Implementation of the composite control. Difference 1: In this example, the createchildcontrol method sets the commandname attribute for the Child control _ button, and its attribute value is submit. Difference 2: The _ button_click event handler is deleted. Difference 3: override the onbubbleevent method of the control base class to check whether the event parameter is an instance of the commandeventargs class. If yes, use the commandname Member of the event parameter to determine whether the event handler onsubmit needs to be triggered and return true.
Summary
This article focuses on the event implementation methods of composite controls, and illustrates the specific application of these implementation methods through typical examples. In general, implementing events for composite controls is not particularly difficult. The key is that developers must master the implementation points of the Inclusion Method and the bubble method on the basis of understanding the implementation events of common controls.