Download the sample source code or material in this article
The previous article introduced the use of the control class render Method Basic knowledge and example applications for widget rendering. This article focuses on another common method to implement control rendering-use the rendercontents method of the webcontrol class to implement control rendering.
Basic knowledge
There are only two cases for server controls: one is visual appearance Element Controls, there is a control that does not have visual elements. If the server control to be developed contains visual elements, it is recommended that developers create a control class inherited from the system. Web. UI. webcontrols. webcontrol base class in most cases. This approach is mainly based on convenience considerations. The webcontrol class provides public attributes, methods, and events related to the appearance of some server controls. You can use the attributes defined by this class Control The appearance and behavior of the server control. For example, the backcolor and forecolor attributes can respectively control the background color and foreground color of the server control. On the controls that can display borders, you can set the borderwidth, borderstyle, and bordercolor attributes, controls the Border width, border style, and border color. The size of the server control can be specified through the height and width attributes. If the control base class is a control class Content It is very cumbersome.
When using the webcontrol base class to render controls, you must use the attributes, methods, and other member objects provided by this class. This is what readers need to master. In addition, the constructors of the base class cannot be ignored. The following describes the webcontrol constructor and describes common member objects.
The webcontrol class includes three constructors, which are used to initialize the new webcontrol class. Instance But there are some small differences between them.
(1) protected webcontrol ()
This constructor is used to initialize a new instance of the webcontrol class that represents the span HTML element. Generally, developers do not directly call this constructor. Instead, it is usually called by the constructor of the derived class to initialize the tagkey attribute as the span enumerated value. In the subsequent example, the tagkey attribute will be rewritten to call this constructor.
(2) Public webcontrol (htmltextwritertag)
Developers can use this constructor to create and initialize a new webcontrol class that uses the specified system. Web. UI. htmltextwritertag Value Instance . The parameter tag indicates one of the enumerated values of htmltextwritertag. Readers may not be familiar with htmltextwritertag. It is an enumeration type, and its enumeration values are mostly HTML tags, such as A, B, bold, and button.
(3) protected webcontrol (string tag)
You can use this constructor to create and initialize a new instance of the webcontrol class marked with the specified HTML. The parameter tag indicates the HTML Tag. When using this constructor, you must note that you cannot directly call this constructor. Instead, it is usually called by the constructor of the derived class to initialize the tagkey and tagname attributes.
After learning about the webcontrol constructor, you must also understand some common attributes and Method . These common member objects are listed below, which are of great significance for implementing control rendering.
(1) attributes
This attribute is used to obtain a set of any features (only for rendering) that do not correspond to the properties of the Control. Its Attribute type is attributecollection.
(2) controlstyle attributes
This attribute is used to obtain the style of the server control, which is of the style type. The controlstyle attribute encapsulates all appearance attributes of the webcontrol class, such as bordercolor and font.
(3) tagkey attributes
This attribute is used to obtain the system. Web. UI. htmltextwritertag value corresponding to this server control. Its Attribute type is htmltextwritertag enumeration.
(4) protected virtual void addattributetorender (htmltextwriter writer );
This method adds HTML attributes and styles to the specified system. Web. UI. htmltextwriter. Note that the corresponding methods in the base class must be called during the rewriting process.
(5) Public void applystyle (Style S );
This method copies all non-blank elements of the specified style to the control and overrides all existing style elements of the control.
(6) Public void mergestyle (Style S );
This method copies all non-blank elements of the specified style to the control, but does not overwrite any existing style elements of the control.
(7) protected override void render (htmltextwriter writer); Method
This method overwrites control. render.
(8) protected virtual void rendercontents (htmltextwriter writer );
This method presents the control content to the specified writer. If you want to write text or other content to the control label, you need to override this method. If you want to use the default logic to present the child control, you must call the corresponding methods in the base class.
You may have noticed two methods in the webcontrol base class: render and rendercontents. According to the content described above, the control base class includes the render method. Because the webcontrol class inherits from the control class, it is beyond reproach to include the render method in the webcontrol class. However, there is an rendercontents method in the webcontrol class, and this method is very similar to the render method in terms of functions and parameters. Which one should be used in rendering controls?
In fact, normally, if the server control is derived from the webcontrol base class, the render method is rarely used, and the rendercontents method is mainly used to render the control. To illustrate the causes, we must understand the implementation logic of the render method in the webcontrol base class.
The implementation schematic code of the render method in the webcontrol base class is as follows:
protected override void Render(HtmlTextWriter output)
{
RenderBeginTag(output);
RenderContents(output);
RenderEndTag(output);
}
The implementation of the renderbegintag method in the webcontrol base class is as follows:
public virtual void RenderBeginTag(HtmlTextWriter output)
{
AddAttributesToRender(output);
HtmlTextWriterTag tagKey = TagKey;
if(tagKey != HtmlTextWriterTag.Unknown)
{
output.RenderBeginTag(tagKey);
} else {
output.RenderBeginTag(this.TagName);
}
}
The implementation of the rendercontents method in the webcontrol base class is as follows:
Protected override void rendercontents (htmltextwriter output ){
// Use the default logic to present the child control. Therefore, you must call the methods in the base class.
Base. Render (output );
}
By analyzing the code above, we can draw the following conclusions:
1. To implement control rendering in a class derived from webcontrol, you must overwrite one or more methods such as addattributestorender, renderbegintag, renderendtag, and rendercontents without rewriting the render method.
2. Rewrite addattributestorender, renderbegintag, renderendtag, rendercontents, and other methods are very important (note the conditions and precautions for rewriting these methods). Otherwise, the server control may lose tags, this will seriously affect the rendering of server controls.
3. When the content in the control label of the server is displayed, the rendercontents method must be rewritten.
This section describes some basic knowledge about the webcontrol class. Especially for the schematic Code listed above, you need to understand it. This plays an important role in implementing control rendering.
Application Example
I believe that when you browse various websites, you will often see similar texts such as "Contact Us. When you click the text, the operating system will automatically open its own mail client software, prompting you to send an email. In this example, a custom Server Control rendercontentscontrol is implemented to display hyperlinks containing "mailto: Email Address. Example 1 in this example:
Figure 1
1. the hyperlink text "my email address" is displayed on the page ". When you click the link, the system sends an email to the my@mysample.com ".
Before implementing the preceding controls, you should first analyze the following: this control contains the appearance Element For example, the text size, color, and whether it is in bold. Therefore, the control base class should not inherit from the control class, but from the webcontrol class. In this way, developers do not have to implement these style attributes on their own. Content .
The following lists the source code of the rendercontentscontrol. CS file that implements custom server controls.
Using system;
Using system. componentmodel;
Using system. Security;
Using system. Security. permissions;
Using system. Web; using system. Web. UI;
Using system. Web. UI. webcontrols;
Namespace usingrendercontentscontrol {
[
Aspnethostingpermission (securityaction. Demand, level = aspnethostingpermissionlevel. Minimal ),
Aspnethostingpermission (securityaction. inheritancedemand, level = aspnethostingpermissionlevel. Minimal), defaultproperty ("email"), parsechildren (true, "text "),
Toolboxdata ("<{0}: rendercontentscontrol runat = Server> </{0}: rendercontentscontrol> ")
]
Public class rendercontentscontrol: webcontrol {
// Implement email attributes
[Bindable (true)]
[Category ("appearance")]
[Defaultvalue ("")] [localizable (true)]
Public String email
{
Get {
String S = (string) viewstate ["email"];
Return (S = NULL )? String. Empty: S );
}
Set {
Viewstate ["email"] = value;
}
}
// Implement the text attribute
[
Bindable (true), category ("appearance"), defaultvalue (""), localizable (true ),
Persistencemode (persistencemode. innerdefaultproperty)
]
Public Virtual string text
{
Get {
String S = (string) viewstate ["text"];
Return (S = NULL )? String. Empty: S;
}
Set {
Viewstate ["text"] = value;
}
}
// Rewrite the tagkey attribute
Protected override htmltextwritertag tagkey
{
Get {
Return htmltextwritertag.;
}
}
// Rewrite addattributestorender Method
Protected override void addattributestorender (htmltextwriter writer)
{
Base. addattributestorender (writer );
Writer. addattribute (htmltextwriterattribute. href, "mailto:" + email );
}
// Rewrite the rendercontents Method
Protected override void rendercontents (htmltextwriter writer)
{
If (text = string. Empty ){
TEXT = Email;
}
Writer. writeencodedtext (text );
}
}
}
As shown in the above Code, the rendercontentscontrol class inherits from the webcontrol base class. The reason is described above. In addition, the implementation process of the rendercontentscontrol class includes metadata attribute tag, three attributes (email, text, and tagkey), and two methods (addattributestorender and rendercontents. The following sections analyze the content one by one.
Three attributes of Code Description:
The code above mainly includes three attributes: email, text, and tagkey. The email attribute is used to obtain or set the specific email address, and the text attribute is used to obtain or set the text content displayed by the control. The viewstate of the control view is used in both attribute implementations. The view status of the server control is the sum of all its attribute values. Viewstate is often used for the implementation of simple attributes. The tagkey attribute is a rewriting attribute inherited from the webcontrol base class, which is the key content that readers need to understand. The tagkey attribute is rewritten to present the element in the HTML Tag, so that the default span element of the webcontrol class is not displayed. Here, it also implies that the constructor used by the control is protected webcontrol () inherited from webcontrol. You can return to the previous section to see the description of this constructor. It should be noted that if the element to be presented is a member of the htmltextwritertag enumeration, the tagkey attribute should be rewritten. Many common HTML element tags are mapped to htmltextwritertag enumerated values. For example, system. Web. UI. htmltextwritertag. A corresponds to element A, while system. Web. UI. htmltextwritertag. Table corresponds to the table element. If the element to be rendered is not represented by a member of the htmltextwritertag enumeration, we recommend that you overwrite the tagname attribute and return the string to be rendered as an element.
Two Methods for Code Description:
Two important methods are rewritten in the rendercontentscontrol Server Control: addattributestorender and rendercontents.
(1) addattributestorender
This method is used to add an href attribute to the control and set the attribute value to "mailto: email". Email is the attribute that represents the email address described above. When override the addattributestorender method, always follow the control source code demonstration method: first, call the base class method and then perform relevant settings. In this way, you can add styles and other attributes to the server control. In fact, according to the implementation schematic code of the renderbegintag method described above, the addattributestorender method is called by the renderbegintag method of webcontrol.
(2) rendercontents
This method is the core content of this example. It is used to write the hyperlink text specified by the text attribute in the control tag. As shown in the Code, the server control calls the writeencodedtext method of the htmltextwriter instance to encode the text entered by developers in HTML. Generally, HTML encoding should be performed on the text provided by the user to ensure security.
Metadata attribute tag for Code Description:
Metadata property tags are applied before the class and before the attribute implementation. Descriptions of these metadata property tags have been described in previous articles. Readers can refer to articles on how to create a simple server control. The following describes the internal text persistence issues.
Parsechildren (true, "text") is set in the metadata attribute mark before the class "). Persistencemode (persistencemode. innerdefaultproperty) is set in the metadata attribute mark before the text attribute ). The above two settings Add the internal text persistence settings for the control. This setting allows developers to set the text attribute in the control tag code. For example:
<Sample: rendercontentscontrol runat = "server" id = "customercontrol" email = "my@mysample.com"> my email address </sample: rendercontentscontrol>
In the code above, the original text "my mailbox address" should be set by the text attribute (this is the default persistence). However, due to the internal text persistence settings, you can set the control text in the control tag.
To implement internal persistence, use parsechildren (true, "text") to mark the rendercontentscontrol. The first parameter of parsechildren is true, which is used to specify that the page analyzer should analyze the content in the control label as an attribute rather than a child control. The second parameter provides the default internal property name of the control as text. When you use these two parameters to call the parsechildren constructor, the content in the control tag must correspond to the internal default attribute. The persistencemode (persistencemode. innerdefaultproperty) of the text property is used to specify that the visualization designer should serialize this property as the internal content in the control tag.
Generally, the webcontrol class uses persistchildren (false) and parsechildren (true) to control the persistence of attributes during design and analysis. These two attributes are inherited by the control and must be applied only when you want to change the inherited settings. Persistchildren informs the designer whether to save the child control of the server control as a nested internal control. The "false" parameter indicates that the internal content corresponds to the property instead of the Child control. Parsechildren is described in the previous section. If the persistence of the webcontrol class applies to your control at design time and analysis time, you do not have to override persistchildren and parsechildren inherited from webcontrol.
The following lists the source code of the default. aspx file used to test the server control:
<% @ Page Language = "C #" autoeventwireup = "true" codefile = "default. aspx. cs" inherits = "_ default" %>
<% @ Register tagprefix = "sample" assembly = "usingrendercontentscontrol" namespace = "usingrendercontentscontrol" %>
<! Doctype HTML public "-// W3C // dtd xhtml 1.0 transitional // en" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns = "http://www.w3.org/1999/xhtml">
<Head id = "head1" runat = "server">
<Title> display controls using rendercontents </title>
</Head>
<Body>
<Form ID = "form1" runat = "server">
<Div>
<Sample: rendercontentscontrol runat = "server" id = "customercontrol" font-bold = "true" font-size = "small" forecolor = "blue" email = "my@mysample.com"> my email address </sample: rendercontentscontrol>
</Div>
</Form>
</Body>
</Html>
As shown in the bold code above, the rendercontentscontrol control sets font-bold, font-size, forecolor, email, and other attributes, and also sets text content between control tags. Of course, you can also set the text attribute value to the same text content. The above code is relatively simple and will not be described here.
In this example, we need to master the rendercontents and addattributestorender methods and the use of tagkey attributes. It is worth noting that although the code of the server control is complicated, the structure is very simple. Do not be overwhelmed by complicated style settings and client behavior code, but be aware of the use process of the two key methods.
After the server control is developed, it is best to view its HTML code and compare the server code with the HTML code to find out what HTML code each server control code presents. Through this method, I believe that the reader can have a deeper understanding of the rendering method of the server control. The following code is displayed when you run the preceding page in a browser and view the relevant HTML source file:
<! Doctype HTML public "-// W3C // dtd xhtml 1.0 transitional // en" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns = "http://www.w3.org/1999/xhtml">
<Head id = "head1">
<Title> display controls using rendercontents </title>
</Head>
<Body>
<Form name = "form1" method = "Post" Action = "default. aspx" id = "form1">
<Div>
<Input type = "hidden" name = "_ viewstate" id = "_ viewstate" value = "/wepdwullteyntqwnjqymdjkzolj3pymgs2hmzn9mu6ogt9v + 5ag"/>
</Div>
<Div>
<A id = "customercontrol" href = "mailto: my@mysample.com" style = "color: Blue; font-size: small; font-weight: bold; "> my email address </a>
</Div>
</Form>
</Body>
</Html>
By observing the above code, we can see that the result of the custom Server Control rendercontentscontrol is the code shown in bold, which is finally displayed as a <A> flag indicating a hyperlink, these include attributes such as href, style, and text. Their values are closely related to the property settings of the rendercontentscontrol control in the source code of the default. aspx file. For example, the email attribute value is eventually displayed as the href attribute value. Readers can view the results by themselves, which is helpful for understanding the display of controls.
Summary
This article mainly introduces some basic knowledge of the webcontrol class, and uses this basic knowledge to create a simple control rendering instance. In fact, the reader should be able to sum up and create custom server controls inherited from the webcontrol base class. The most important method is to rewrite rendercontents. It is very important to remember this. So far, I have used two articles to introduce how to render controls. In future articles, we will introduce the attributes of controls.