Asp.net| Server | control
To set the appearance of a composite control, a composite control must provide some style properties, especially for child controls. In this article, we will focus on two ways to implement style properties for a composite control.
1, upload some style properties
Before you implement style properties for a composite control, the reader should first understand the basic concept of style bubbling. Style bubbling is used to implement the style properties of a composite control. Because there are multiple child controls in a composite control, the style properties of these child controls may, in some cases, interfere with the style properties of the composite control, causing the style property to clutter. For a more explicit definition of the style properties of a composite control, you can take the style properties of a child control as a top-level style property, which is called "style bubbling."
Typically, developers can face two situations: one is to upload a few style attributes from a child control, and the other is to upload all the style properties in a child control. This section only describes the implementation methods for the first case, while the other one is explained in the following section.
The key to this method of implementing style properties described in this section is to introduce style properties by specifying a key/value pair for the child control's attributes, which uploads the child control's style properties to the composite control top-level property. To facilitate the reader's understanding of this approach, a typical application is listed below.
In this example, a composite control mycontrol is implemented, and a table control is included in its child control collection. Currently, you need to upload the table child control's style properties cellpadding and border to MyControl's top-level style properties. The specific source code is shown below.
public class mycontrol:compositecontrol{
Related code ...
To define an initial value
private int _cellpadding = 0;
private int _border = 1;
......
Defines a style property that is similar to the style properties of the table control cellpadding and border
public int cellpadding{
get {return _cellpadding;}
set {_cellpadding = value;}
Implement Properties Border
public int border{
get {return _border;}
set {_border = value;}
......
Overriding the CreateChildControls method
protected override void CreateChildControls () {
Related code
......
Table T = new table (); To add a previously defined attribute to a key/value pair
T.addattributes.add ("cellpadding", _cellpadding.tostring ());
T.addattributes.add ("Border", _border. ToString ());
......
}
}
The above code shows some of the key source code for MyControl, which focuses on key steps to implement some of the style property bubbles. (1) Initialize the fields of the top-level style properties, and define the initial values if necessary. (2) Define a property with the same name as the style property of the child control that needs to be upgraded. Attributes cellpadding and border are defined in the code above. (3) Introduce the property defined in step 2nd in the Attributes key/value pair of the child control.
When you set the property values for style properties cellpadding and border in mycontrol, you actually set the cellpadding and border property values for the table child control. Style bubbling can be achieved with the above 3 key steps.
If you look closely, you can see that there are some problems with this style-bubbling approach described above: first, this method only applies to upgrading a few style properties in a child control. If you need to upgrade all of the child control's style properties and still use this method, it is tedious and prone to error. Secondly, the implemented style attribute lacks logic and organization. In some cases, for example, the same style property for multiple child controls needs to be upgraded to the top-level property, using this method can cause confusion.
To address these issues, the following is an implementation of all style attributes for uploading child controls.
2, upload all style properties
In the previous section, you explained the content about implementing the style of a composite control, but that implementation could only implement the style of the child control section and lacked logic and organization. The method that implements the style properties of the composite control described in this section effectively avoids the above problems. It implements the properties of multiple delegates, which define the style of width and height for each child control, and, further, the complex style properties of the style type corresponding to each child control, for example, TextboxStyle, ButtonStyle. In this way, the child control's style properties are uploaded to the top-level property, so that the child control's appearance can be set.
Obviously, the key to implementing a child control's style property upload is to implement the complex style properties of the style type. For this reason, developers must provide custom view state management for complex style properties. The reader should note that the view state of the composite control differs from the normal control view state. Because the composite control contains child controls, the corresponding view state includes both the view state of the parent control and the view state of the complex style properties corresponding to the child control. For example, the view state of a control in the previous instance contains 3 parts: The view state of the parent control itself, the ButtonStyle view state, and the TextboxStyle view state. In addition, the specific implementation process and the implementation of common complex properties are basically consistent.
I wonder if the reader remembers the composite control in the previous article, that is, a composite control consisting of a text box textbox and a button compositeevent. Here, we add the top-level style properties ButtonStyle and TextboxStyle to the control that have the control set. The source code for the control class Compositeevent is listed below.
Using System;
Using System.Web.UI;
Using System.Web.UI.WebControls;
Using System.ComponentModel;
Using System.ComponentModel.Design;
Namespace webcontrollibrary{
public class Compositeevent:compositecontrol {
declaring variables
Private Button _button;
Private TextBox _textbox;
private static readonly Object Eventsubmitkey = new Object ();
Declaring a style variable
Private Style _buttonstyle;
Private Style _textboxstyle;
Defines the property buttontext that specifies the text on the button
[Bindable (True), Category ("appearance"), DefaultValue (""), Description ("Get or set the text to display on the button")]
public string ButtonText {
get {ensurechildcontrols (); return _button. Text; }
set {EnsureChildControls (); _button. Text = value; }
}
Defines the property text, which represents the input of a 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;
}
}
Defining ButtonStyle Properties
[Category ("style"), Description ("Style properties of Button"), DesignerSerializationVisibility ( designerserializationvisibility.content), Notifyparentproperty (True), PersistenceMode ( Persistencemode.innerdefaultproperty)]
Public virtual Style ButtonStyle {
get {
if (_buttonstyle = = null) {
_buttonstyle = new Style ();
if (istrackingviewstate) {
((IStateManager) _buttonstyle). TrackViewState ();
}
}
return _buttonstyle;
}
}
Defining TextStyle Properties
[Category ("style"), Description ("Set style properties for TextBox"), DesignerSerializationVisibility ( designerserializationvisibility.content), Notifyparentproperty (True), PersistenceMode ( Persistencemode.innerproperty)]
Public virtual Style TextboxStyle {
get {
if (_textboxstyle = = null) {
_textboxstyle = new Style ();
if (istrackingviewstate) {
((IStateManager) _textboxstyle). TrackViewState ();
}
}
return _textboxstyle;
}
}
Implementing 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);
}
}
Recreatechildcontrls method to rewrite Icompositecontroldesigneraccessor interface
protected override void Recreatechildcontrols () {ensurechildcontrols ();}
Overriding the CreateChildControls method to add a child control to a composite control
protected override void CreateChildControls () {
Controls.clear ();
_button = New button ();
_textbox = new TextBox ();
_button.id = "BTN";
_button. Click + + new EventHandler (_button_click);
_button.commandname = "Submit";
This. Controls.Add (_button);
This. Controls.Add (_textbox);
}
Overriding the OnBubbleEvent method, performing 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;
}
Overriding the Render method to render other HTML code in the control
protected override void Render (HtmlTextWriter output) {
AddAttributesToRender (output);
if (_textboxstyle!= null) {
_textbox.applystyle (TextboxStyle);
}
if (_buttonstyle!= null) {
_button. ApplyStyle (ButtonStyle);
}
Output. AddAttribute (Htmltextwriterattribute.border, "0px");
Output. AddAttribute (htmltextwriterattribute.cellpadding, "5px");
Output. AddAttribute (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 ();
}
State management of complex style attributes, overriding 3 related methods LoadViewState, SaveViewState, trackviewstate
protected override void LoadViewState (object savedstate) {
if (savedstate = = null) {
Base. LoadViewState (NULL);
Return
}
if (savedstate!= null) {
Object[] MyState = (object[]) savedstate;
if (mystate.length!= 3) {throw new ArgumentException ("Invalid ViewState");}
Base. LoadViewState (Mystate[0]); if (mystate[1]!= null) {
((IStateManager) textboxstyle). LoadViewState (mystate[1]);
}
if (mystate[2]!= null) {
((IStateManager) buttonstyle). LoadViewState (mystate[2]);
}
}
}
protected override Object SaveViewState () {
object[] MyState = new Object[3];
Mystate[0] = base. SaveViewState ();
MYSTATE[1] = (_textboxstyle!= null)? ((IStateManager) _textboxstyle). SaveViewState (): null;
MYSTATE[2] = (_buttonstyle!= null)? ((IStateManager) _buttonstyle). SaveViewState (): null;
for (int i = 0; I [3; i++) {
if (Mystate[i]!= null) {return mystate;}
}
return null;
}
protected override void TrackViewState () {
Base. TrackViewState ();
if (_buttonstyle!= null) {
((IStateManager) _buttonstyle). TrackViewState ();
}
if (_textboxstyle!= null) {
((IStateManager) _textboxstyle). TrackViewState ();
}
}
}
}
If the reader has read the previous article, you should be familiar with the above code. Limited to space, this article does not explain what has been described previously, but focuses on the content of style bubbling.
The content associated with style bubbling can be divided into three parts: one is to define complex style properties for style types: ButtonStyle and TextboxStyle; the second is to apply complex style properties to child controls in the Render method; The third is the Custom view state Management section that implements complex style properties. The implementation of the above three parts is actually the most critical three steps in implementing the child control style upload process. The first two parts of the implementation is relatively simple, this is not explained. The implementation of the last section is highlighted below.
The third part mainly realizes the custom state management of the complex style attribute. In the TrackViewState method, TrackViewState are invoked on the base class, _textboxstyle, and _buttonstyle respectively. In the SaveViewState method, you first define an array of MyState objects, and then, in order, save the view state data for the base class, TextBox, and button into the MyState and return. In the LoadViewState method, the implementation will load the first part of the saved state data (savedstate) into the base class, the second part is loaded to the TextboxStyle, and the third part is loaded to the ButtonStyle, The reason why loading in this order corresponds to the save order in the SaveViewState method.
The following is a fragment of the application code for the Compositeevent control. Please note that the ButtonStyle and TextboxStyle are marked as internal nested form attributes, and the user can complete the child control's appearance settings by setting the style properties.
<%@ Page language= "C #" autoeventwireup= "true" codefile= "Default.aspx.cs" inherits= "_default"%>
<%@ Register tagprefix= "Sample" assembly= "Webcontrollibrary" namespace= "Webcontrollibrary"%>
! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<script runat= "Server" >
void Demo1_submit (object sender, EventArgs e)
{
Lbmessage.text = "You have just entered is:" + demo1. Text;
}
</script>
<title> implement styles for composite controls </title>
<body> <form id= "Form1" runat= "Server"
<div>
<sample:compositeevent id= "Demo1" runat= "Server" buttontext= "Submit"
<textboxstyle width= "198px" height= "20px" borderwidth= "1px" backcolor= "Orange"
</TextBoxStyle>
<buttonstyle width= "84px" height= "24px" borderwidth= "1px" borderstyle= "dotted" > </ButtonStyle>
</Sample:CompositeEvent>
<BR/>
<asp:label id= "Lbmessage" runat= "Server"
</asp:Label> </div>
</form>
</body>
The example application effect diagram is listed below.
Figure 1 Effect chart
As shown in Figure 1, the appearance of text boxes and buttons in a composite control is set by the ButtonStyle and TextboxStyle properties. Readers can set the style of text boxes and buttons just as you would for individual controls. Of course, these properties must be included in the <ButtonStyle> and <TextBoxStyle> tags. This is to be borne in mind.
3. Summary
This chapter describes specific ways to implement style properties for composite controls, including uploading partial style properties and uploading all style attributes. For developers, you need to choose a different approach depending on your situation. In general, for simple composite controls, it is recommended that you use the method of uploading some style properties, and for complex, composite controls, it is recommended that you use the upload all style properties.