Spring Fish-11-21
Summary
This article describes how to enable ASP: validator control to check the implementation of our Web user control. Validatable indicates that it can be verified by the <asp: validator.../> series of controls.
Key and difficulty: Introduce validationpropertyattribute to the class.
Simulation
Preface
In the most recent project of the author, a user is required to select data composed of provinces, cities, and counties. Finally, you can select the district/county. Because of the large number of administrative regions in China, it is reasonable to use the "three-level linkage" selector () to facilitate user operations. My initial thought was to use a simple, easy-to-implement logic without the need to mix the "three-level linkage" (in some cases quite complex) logic with other business logic. (For some developers who are disgusted with logical chaos, this will make them depressed) and should avoid this situation. So I want to package the three drop-down lists with an ascx (ASP. NET web user control). Is this OK? I started my attempt without careful consideration. When the finished product is taken out and debugged successfully and put into the project, I found that I have done the following work:
1. Centralized logic for accessing back-end data sources
2. The upper-lower restrictive relationship among provinces, municipalities, and counties is achieved.
3. The container must be able to access the current value. For this reason, I must implement selectedvalue public property for control, and the attribute must be accessible by get and set accessors.
4. The post back data handler interface must be implemented
5. Implement validatable
<% @ Control Language = " C # " Autoeventwireup = " False " Codebehind = " Regionlist. ascx. CS " Inherits = " Topnamespace. Controls. regionlist " Targetschema = " Http://schemas.microsoft.com/intellisense/ie5 " %>
< ASP: dropdownlist ID = Provincelist Runat = Server Width = 100 Autopostback = True />
< ASP: dropdownlist ID = Citylist Runat = Server Width = 100 Autopostback = True />
< ASP: dropdownlist ID = Zonelist Runat = Server Width = 100 />
The HTML part is extremely simple. Only the <asp: dropdownlist/> labels of the three servers are listed. The three select statements are displayed on the client. You can select the province, city, and district/county respectively.
I believe everyone has developed similar applications. Here we will only briefly describe the basic ideas.
001 initialization process
In the code behind section, you must first enable the control to complete the initialization process: when the control loads the page for the first time, the user wants each select to be empty (the initial status when no valid data is selected ), however, the first select statement should load all provincial data by default. For Web user control, we can use a default page_load process. Page_load is defined in the private void initializecomponent process (the private void initializecomponent process is defined in the override protected void oninit process), but the page_load process occurs too early. We re-intercept another late control event: prerender. In the initializecomponent process, enter this. after prerender + = is followed by two consecutive [Tab] keys, A _ prerender (Object sender, eventargs e) process is automatically created. In this process, we load data for the first <asp: dropdownlist/>. Before this process, we assume that users can obtain administrative region data stored in a certain data format. We use a data source that can be bound to save the data and bind it to <asp: dropdownlist/> logically.
Note: This data binding process only occurs when the control is loaded for the first time. In the post back process, <asp: dropdownlist/> you can maintain your own data (using the viewstate mechanism ).
002 linkage Logic
After the analysis, the normal logic is that when you select a provincial administrative region, the data of the municipal area under the current provincial node should be loaded. When selecting municipal administrative areas, the data of county-level administrative areas of the corresponding area should be loaded. The selectedindexchanged evnet.
003 selectedvalue public property
When web user control appears in the container as a whole, the container should be able to access its value at the running time of the server. Otherwise, we will lose the foundation of the application. Based on the principle of high cohesion and low coupling, public property is generally used. Define their set and get access processes respectively:
1. Get process: return the selectedvalue value of <asp: dropdownlist/> in level 3 (District/County ).
2. Set process: Is it as simple as that?
Let's consider the next basic fact:
The Set accessors process, that is, the control must be set with a specified value when it is loaded. In this case, in addition to the reverse process of the get process (set level 3), the set accessors must also be set to Level 3. <asp: dropdownlist/> Fill in the data, and set the key to be equal to the current selectedvalue public property. As you can see, municipal data also needs to be set up in the upper-level area of the current district and county, which is traced back to the provincial area. The implementation of this process is required.
005 post back data handling implementation
This feature is required for backend control of the processing value, because the control must be able to maintain its own server value between the post back, which requires our control to implement ipostbackdatahandler interface. I have mentioned this logic in my previous discussions. The specific implementation method requires a front-end <input.../> element with the same clientid as the control server. This is the same as the validatable Implementation discussed below --
004 validatable implementation
This development requirement comes from the title of this article: "validatable control"-control that can be tested by <asp: validator.../>.
During the project, the customer suddenly asked this "linkage selector" not to be left blank, and we must verify whether the control has a valid value at the time of Form submission, this verification process is implemented on the client. Generally, the <asp: validator.../> series of controls only validate some built-in standard server-side input control.
How can we make our web user control verifiable? Find the relevant msdn chapters:
(Original ):
Use the controltovalidate property to specify the input control to validate. this property must be set to the ID of an input control for all validation controls t for the customvalidator control, which can be left blank. if you do not specify a valid input control, an exception will be thrown when the page is rendered. the ID must refer to a control within the same container as the validation control. it must be in the same page or user control, or it must be in the same template of a templated control.
The standard controls that can be validated are Textbox, ListBox, dropdownlist, radiobuttonlist, htmlinputtext, htmlinputfile, htmlselect and htmltextarea.
Note for an input control to be validated, the system. Web. UI. validationpropertyattribute must be applied to the control.
(Set the ID of the input control to specify the verification target. The verified control must be an input control. Currently, it must be of several specific types: The above bold Section.
Note: to configure a control as validatable control, you must apply validationpropertyattribute to Control .)
The last sentence is critical. It also pointed out the direction for us.
Add the validationpropertyattribute Attribute before the class definition and specify the feature to be verified as selectedvalue.
[Validationpropertyattribute ( " Selectedvalue " )]
Public Class Regionlist: system. Web. UI. usercontrol
{
...
In this way, we can append a validator for our control in the usual way:
< ASP: requiredfieldvalidator ID = Regionrequiredfieldvalidator Controltovalidate = "Regionlist" Display = None Errormessage = "Region" Runat = "Server" />
If the above attribute is not set, an error occurs when parsing Aspx.
In addition, we know that the <asp: validator.../> series validation controls work on the client. We analyze the target HTML generated on the front-end of the following page. We analyze A validator instance that verifies different <asp: textbox.../>:
< Span ID = "Projectinfo_projectidrequiredfieldvalidator" Controltovalidate = "Projectinfo_projectnobox" Errormessage = "Project code" Display = "NONE" Evaluationfunction = "Requiredfieldvalidatorevaluateisvalid" Initialvalue = "" Style = "Color: red; display: none ;" > </ Span >
AboveCodeTake the text of the front-end HTML of a page, and we find that each <asp: validator... /> are constructed into a common element of the front end, and its behavior is created by ASP.. net. We do not need to perform detailed analysis, but we can see that controltovalidate is written to the front-end attribute, and value is a unique ID in a page. We can see from the following comparison that the backend-to-front-end controltovalidate has changed. This change is based on the inherent mechanism of ASP. NET. By writing the attribute to the front-end, you can find the input element parsed to the front-end. Then, read the front-end value through a certain mechanism and check and process it.
In this way, we know what we should accomplish:
1. The back-end value of control must be reflected to the front-end in a certain way.
2. An input element that can be accessed by the front-end ID must exist.
3. The value must be changed by the front-end script before post to the backend.
The implementation method is as follows:
1. Write a special <input type = hidden.../> element for control during control prerender:
System. Web. UI. webcontrols. webcontrol Control = New Webcontrol (system. Web. UI. htmltextwritertag. Input );
Control. Attributes. Add ( " ID " , This . Clientid );
Control. Attributes. Add ( " Type " , " Hidden " );
Control. Attributes. Add ( " Value " , This . Viewstate [ " Hiddenvalue " ] = Null ? This . Selectedvalue :( String ) This . Viewstate [ " Hiddenvalue " ]);
This . Controls. Add (control );
About the above SourceProgram, We can see that we give <input type = hidden... /> the ID attribute is written, and the value is the clientid feature of control. vaue uses the viewstate mechanism to keep this value between post back. In this way, the backend value is written to the front end, And the <input type = hidden.../> element can be accessed by validator.
2. As front-end user operations change, you need to write a script to the front-end so that <input type = hidden.../> can change with the third-level element selectedindexchange frontend event.
System. Text. stringbuilder Builder = New System. Text. stringbuilder ();
Builder. appendformat ( " <SCRIPT> " );
Builder. appendformat ( " Jesse_list = Document. All ['{0}']; " , This . Mainlist. clientid );
Builder. appendformat ( " Jesse_hidden = Document. All ['{0}']; " , This . Clientid );
Builder. append ( @"
Jesse_list.attachevent ( ' Onchange ' , _ Set_typelist_value );
Function _ set_typelist_value () {
Jesse_hidden.value=Jesse_list.value;
}
</ Script > " );
String Script = Builder. tostring ();
If ( ! This . Page. isstartupscriptregistered ( " Region_list_client " )) This . Page. registerstartupscript ( " Region_list_client " , Script );
Construct the script block and register it to the front-end.
In this way, we have basically implemented a relatively complete "linkage" control. If a specific logic is encountered, we should modify it accordingly. To apply it to aspx or other ascx, you can use validator in the normal <asp: input control series.
This article was completed in a rush. I don't know if it is to clarify the problem and help everyone.
BelowSource codeIt is based on the actual project of the author and is for reference only:
Http://files.cnblogs.com/jesse/RegionList_Control_Sample_2004-11-21.zip
Note: The Source Code may need to be modified to compile and run properly.