Exercising HtmlTextWriter The LoginUI


Exercising HtmlTextWriter ” The LoginUI Example

We'll now develop the LoginUI control, which uses the methods of the HtmlTextWriter class to render a user interface that enables a user to log into a Web site. Unlike the earlier samples in this chapter, LoginUI exercises the style-rendering capabilities of HtmlTextWriter . LoginUI renders two HTML text boxes (one for name information, and one for password information) and a button to submit the form, as shown in Figure 8-2. LoginUI renders these elements as cells in an HTML table. At this stage, LoginUI merely renders a user interface; it does not have the ability to process data or handle events. We will implement that functionality in Chapter 9, "Control Life Cycle, Events, and Postback."

Figure 8-2. LoginUITest.aspx viewed in a browser. The page demonstrates the UI rendered by the LoginUI control.

graphics/f08hn02.jpg

To demonstrate the functionality of the HtmlTextWriter class, the LoginUI control derives from Control and exposes many style- related properties, such as BackColor , BorderStyle , and FontFamily . Note, however, that LoginUI is an "artificial" control that we've developed purely to exercise the methods of Html ­TextWriter . If your control needs style-related functionality, you should derive from WebControl , which exposes strongly typed style properties.

At this point, it might appear that we are doing a lot of extra work to render a user interface that could be rendered as a few lines of raw HTML. However, if you want to create reusable controls, you should use strongly typed styles and the tag-rendering capabilities of HtmlTextWriter . Also bear in mind that the LoginUI control is unnecessarily long because we created it for demonstration purposes without reusing the functionality of the WebControl class. Listing 8-5 contains the code for the LoginUI control.

Listing 8-5 LoginUI.cs
 usingSystem; usingSystem.ComponentModel; usingSystem.Drawing; usingSystem.Globalization; usingSystem.Web.UI; usingSystem.Web.UI.WebControls; namespaceMSPress.ServerControls{ publicclassLoginUI:Control{ [ Bindable(true), 
 Category("Appearance"), DefaultValue(typeof(Color), ""), Description("Thebackgroundcolor"), //TheWebColorConverterisatypeconverter //thatallowsastringspecifyinganHTMLcolor //tobeconvertedtoaSystem.Drawing.Colortype. TypeConverter(typeof(WebColorConverter)) ] publicColorBackColor{ get{ objecto=ViewState["BackColor"]; return(o==null)?Color.Empty:(Color)o; } set{ ViewState["BackColor"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(typeof(Color), ""), Description("Thebordercolor"), TypeConverter(typeof(WebColorConverter)) ] publicColorBorderColor{ get{ objecto=ViewState["BorderColor"]; return((o==null)?Color.Empty:(Color)o); } set{ ViewState["BorderColor"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(BorderStyle.NotSet), Description("Theborderstyle") ] publicBorderStyleBorderStyle{ get{ objecto=ViewState["BorderStyle"]; return(o==null)?BorderStyle.None:(BorderStyle)o; } set{ ViewState["BorderStyle"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(typeof(Unit), ""), Description("Theborderwidth") ] publicUnitBorderWidth{ get{ objecto=ViewState["BorderWidth"]; return(o==null)?Unit.Empty:(Unit)o; } set{ if(value.Value<0) thrownewArgumentOutOfRangeException("value"); ViewState["BorderWidth"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("Thetexttodisplayonthebutton") ] publicstringButtonText{ get{ strings=(string)ViewState["ButtonText"]; return(s==null)?String.Empty:s; } set{ ViewState["ButtonText"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("Thefont") ] publicstringFontFamily{ get{ strings=(string)ViewState["FontFamily"]; return(s==null)?String.Empty:s; } set{ ViewState["FontFamily"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(typeof(FontUnit), ""), Description("Thesizeofthefont") ] publicFontUnitFontSize{ get{ objecto=ViewState["FontSize"]; return(o==null)?FontUnit.Empty:(FontUnit)o; } set{ ViewState["FontSize"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(false), Description("Theweightofthefont") ] publicboolFontBold{ get{ objecto=ViewState["FontBold"]; return(o==null)?false:(bool)o; } set{ ViewState["FontBold"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("ThelabelfortheNametextbox") ] publicstringNameLabel{ get{ strings=(string)ViewState["NameLabel"]; return(s==null)?String.Empty:s; } set{ ViewState["NameLabel"]=value; } } [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("ThelabelforthePasswordtextbox") ] publicstringPasswordLabel{ get{ strings=(string)ViewState["PasswordLabel"]; return(s==null)?String.Empty:s; } set{ ViewState["PasswordLabel"]=value; } } //TheidattributetorenderontheHTMLbuttontag. //Theidattributeenablesclient-sidescripttoaccess //anHTMLelementandmustbeuniqueforevery //HTMLelementonthepage. //Weusetheservercontrol'sClientIDproperty //astheHTML "id" becauseitisguaranteedto //beuniqueanddoesnothaveanyinvalidcharacters. //TheUniqueIDusestheinvalid ":" character //asaseparator,aswe'llexplaininChapter12. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringButtonID{ get{ returnthis.ClientID+ "_Button"; } } //ThenameattributetorenderontheHTMLbuttontag. //ThenameattributeisrequiredoneveryHTMLform //elementandisusedbytheclienttopostname/value //pairstotheserverwhentheusersubmitstheform. //Ontheserver,thenameisusedbythe //pageframeworktoprocesspostbackdataandmustbe //uniqueforeachcontrolonthepage. //Toenablethepageframeworktohandlepostbackevents, //thenameattributeofanHTMLelementthatcausespostback //(suchasanHTMLbutton)mustequaltheUniqueID //ofthecontrol. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringButtonName{ get{ returnthis.UniqueID+ ":Button"; } } //TheidattributetorenderontheHTMLTextBox //forthepassword.We'llbasethisonthe //ClientIDtoguaranteeauniqueid. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringPasswordInputID{ get{ returnthis.ClientID+ "_Password"; } } //ThenameattributetorenderontheHTMLTextBox //forthepassword.We'llbasethisonthe //UniqueIDtoguaranteeauniquename. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringPasswordInputName{ get{ returnthis.UniqueID+ ":Password"; } } //TheidattributetorenderontheHTMLTextBox //fortheusername.We'llbasethisonthe //ClientIDtoguaranteeauniqueid. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringUserNameInputID{ get{ returnthis.ClientID+ "_UserName"; } } //ThenameattributetorenderontheHTMLTextBox //fortheusername.We'llbasethisonthe //UniqueIDtoguaranteeauniquename. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicstringUserNameInputName{ get{ returnthis.UniqueID+ ":UserName"; } } protectedoverridevoidRender(HtmlTextWriterwriter){ writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing,  "1"); //Youmustpassineachstyleattributebymakinga //separatecalltoAddStyleAttribute. //TheHtmlTextWritercombinesallthestyle //attributesintoasinglesemicolon-delimitedlist, //whichitassignstothestyleHTMLattribute //ontheHTMLtag. if(!BackColor.IsEmpty){ //TheColorTranformer.ToHtmlmethodconvertsa //System.Drawing.Colorobjecttoastringthat //representsthecolorinHTML. writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor)); } if(!BorderColor.IsEmpty){ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, ColorTranslator.ToHtml(BorderColor)); } if((BorderStyle!=BorderStyle.None)&& (BorderStyle!=BorderStyle.NotSet)){ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, BorderStyle.ToString()); } if(!BorderWidth.IsEmpty){ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, BorderWidth.ToString(CultureInfo.InvariantCulture)); } if(FontFamily!=String.Empty){ writer.AddStyleAttribute(HtmlTextWriterStyle.FontFamily,FontFamily); } if(!FontSize.IsEmpty){ writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, FontSize.ToString(CultureInfo.InvariantCulture)); } if(FontBold==true){ writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, "Bold"); } //Renderanidontheoutertag. writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID); writer.RenderBeginTag(HtmlTextWriterTag.Table); writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBeginTag(HtmlTextWriterTag.Td); if(NameLabel!=String.Empty){ writer.Write(NameLabel); } writer.RenderEndTag();//Td writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.AddAttribute(HtmlTextWriterAttribute.Type, "Text"); writer.AddAttribute(HtmlTextWriterAttribute.Name, UserNameInputName); writer.AddAttribute(HtmlTextWriterAttribute.Id, UserNameInputID); writer.AddAttribute(HtmlTextWriterAttribute.Value, String.Empty); writer.RenderBeginTag(HtmlTextWriterTag.Input); //EachcalltoRenderBeginTagmusthaveamatching //calltoRenderEndTag. writer.RenderEndTag();//Input writer.RenderEndTag();//Td writer.RenderEndTag();//Tr writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBeginTag(HtmlTextWriterTag.Td); if(PasswordLabel!=String.Empty){ writer.Write(PasswordLabel); } writer.RenderEndTag();//Td writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.AddAttribute(HtmlTextWriterAttribute.Type,  "Password"); writer.AddAttribute(HtmlTextWriterAttribute.Name, PasswordInputName); writer.AddAttribute(HtmlTextWriterAttribute.Id, PasswordInputID); writer.AddAttribute(HtmlTextWriterAttribute.Value, String.Empty); writer.RenderBeginTag(HtmlTextWriterTag.Input); writer.RenderEndTag();//Input writer.RenderEndTag();//Td writer.RenderEndTag();//Tr writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); writer.AddAttribute(HtmlTextWriterAttribute.Align,  "right"); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.AddAttribute(HtmlTextWriterAttribute.Type,  "Submit"); writer.AddAttribute(HtmlTextWriterAttribute.Name, ButtonName); writer.AddAttribute(HtmlTextWriterAttribute.Id,ButtonID); writer.AddAttribute(HtmlTextWriterAttribute.Value, ButtonText); writer.RenderBeginTag(HtmlTextWriterTag.Input); writer.RenderEndTag();//Input writer.RenderEndTag();//Td writer.RenderEndTag();//Tr writer.RenderEndTag();//Table } } } 

The LoginUI control invokes the AddAttribute , AddStyleAttribute , RenderBeginTag , and RenderEndTag methods of the HtmlTextWriter instance to build up the output to be added to the response stream. You must provide all the attributes and style attributes of a tag before invoking the RenderBeginTag method because the HtmlTextWriter object needs the attribute information before it can start writing a tag. You must pass in each style attribute by making a separate call to AddStyleAttribute . The HtmlTextWriter combines all the style attributes into a single semicolon-delimited list, which it assigns to the style HTML attribute on the HTML tag (style=" background-color :Gainsboro; border-color :Gray; border-style :Solid; border-width :1px;font-family:Verdana;font-size:10pt;font-weight:Bold;") . Note that every RenderBeginTag method call must have a matching RenderEndTag call. This also applies to tags that do not have corresponding closing tags in HTML, such as the <input> tag.

Notice that LoginUI renders name and id attributes for each HTML form element that it generates (the two text boxes and the button). The id attribute is useful to access the element in client-side script and must be unique for each element to which it is assigned. We've created unique id attributes based on the ClientID property, which the page framework provides specifically for this purpose. It is good practice to render an id attribute for every HTML element that can have client-side behavior. WebControl renders the ClientID property as the value of the HTML id attribute by default.

If your control renders form input elements, you must render a unique name attribute on each form element to enable that element to participate in postback data processing. The browser uses the name attribute to post name/value pairs to the server when the user submits the form. On the server, the ASP.NET page framework uses the name attribute to route events and data to the control after postback. The standard ASP.NET form controls assign the UniqueID of the control to the name attribute. Because we have multiple form elements, we have created unique names for each element based on the UniqueID of the control.

As we mentioned earlier, LoginUI does not have postback data-processing or event-handling capabilities. However, we've added name attributes to the form elements of LoginUI because we'll derive from this control in Chapter 9 to develop a control that implements postback data-processing and event-handling functionality.

Listing 8-6 shows a page that uses the LoginUI control and sets its properties.

Listing 8-6 LoginUI.cs
 <%@PageLanguage="C#" %><%@RegisterTagPrefix="msp"  Namespace="MSPress.ServerControls"  Assembly="MSPress.ServerControls" %> <html> <body> <formrunat="server"> <br> <msp:LoginUIid="LoginUI1" runat="server" ButtonText="Submit"  NameLabel="LoginName:" PasswordLabel="Password:" BackColor="Gainsboro" BorderColor="Gray"  BorderStyle="Solid" BorderWidth="1px"  FontFamily="Verdana"  FontSize="10pt" FontBold="True" /> <br> <br> </form> </body> </html> 

If you view the source for the page shown in Figure 8-2, you will see that the HTML rendered by the LoginUI instance is similar to the following HTML:

 <tablecellspacing="1" id="LoginUI1" style="background-color:Gainsboro; border-color:Gray;border-style:Solid;border-width:1px;font-family: Verdana;font-size:10pt;font-weight:Bold;"> <tr> <td>LoginName: </td> <td> <inputtype="Text" name="LoginUI1:UserName"  id="LoginUI1_UserName" value="" /> </td> </tr> <tr> <td>Password: </td> <td> <inputtype="Password" name="LoginUI1:Password"  id="LoginUI1_Password" value="" /> </td> </tr> <tr> <tdcolspan="2" align="right"><inputtype="Submit"  name="LoginUI1:Button" id="LoginUI1_Button" value="Submit" /> </td> </tr> </table> 

Notice that the style properties that we set on the control are rendered on the opening <table> tag as a semicolon-delimited list, which is the value of the style HTML attribute. We did not write this HTML syntax. The HtmlTextWriter object generated it for us because, in the Render method of the LoginUI control, we called the AddAttribute method to supply style attributes before rendering the tag. All the attributes that you provide by using the AddAttribute and AddStyleAttribute methods before invoking a RenderTag method are rendered on the corresponding tag.



Developing Microsoft ASP. NET Server Controls and Components
Developing Microsoft ASP.NET Server Controls and Components (Pro-Developer)
ISBN: 0735615829
EAN: 2147483647
Year: 2005
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net