The User Control Model


The User Control Model

Processing a user control is similar to processing a page, which we described in Chapter 2, "Page Programming Model." A user control consists of a declarative .ascx file and an optional code-behind file (which we will soon describe). The transformation of the source files into a server control works like this: When a page with a user control is requested , the page parser parses the .ascx file specified in the Src attribute and generates a class that derives from System.Web.UI.UserControl . The parser dynamically compiles the class into an assembly, thus defining a new type that corresponds to the user control. (In the case of a user control that uses the Visual Studio .NET code-behind model, the page parser generates a class that derives from a UserControl -derived code-behind class, as you will soon see.) If the .ascx page contains a Control directive that provides a ClassName attribute, the value supplied for the ClassName attribute becomes the name of the parser-generated class. Thus, in the example discussed in the "Converting a Page to a User Control" section, the parser will generate a class named RequiredTextField because we specified ClassName="RequiredTextField" in the Control directive.

While the ClassName attribute is optional, you should always use it to provide a name for the strong (exact) type of your user control. The type name is needed to cast a control from a base type to its exact type. For example, if a user invokes the FindControl method (that returns an object of type Control ) to get your control, the user code must downcast the returned object to the exact type of your user control to access your control's object model. Here is an example:

 RequiredTextFieldtextField= (RequiredTextField)Page.FindControl(requiredTextField1); //Thenextlinewouldnotbepossiblewithout //castingthereturnedcontroltoRequiredTextField //becausetheControlclassdoesnotexposeaTextproperty. stringtext=textField.Text; 

If you do not specify a ClassName attribute, the parser provides a default name for the autogenerated class. The parser-supplied name of the autogenerated class generally consists of the suffix _ascx appended to the filename ”for example, RequiredTextField_ascx . However, the parser is not guaranteed to abide by this naming pattern, and a user could encounter an error when using the assumed default type name. Hence, we recommend that you always specify the ClassName attribute.

When processing a user control, the page framework performs two additional steps that are not needed for a custom (compiled) control:

  1. It parses the declarative syntax to generate the source code for a managed class that derives from System.Web.UI.UserControl.

  2. It dynamically compiles the autogenerated class into an assembly.

These steps are executed only once ”the first time a page containing the user control is requested ”and they do not result in any additional overhead on subsequent requests .

Viewing the Class Generated by the Parser from an .ascx File

If you would like to see the class that is autogenerated by the page parser from an .ascx file, perform the following steps:

  1. Add a debug attribute at the top of the page that contains the user control ( <%@ Page debug="true" %> ).

  2. Introduce a syntax error (such as an unbalanced parenthesis or a missing colon statement terminator) in a server-side script block in your user control, and save the file.

  3. Request a page that contains the user control in your browser. The server will return an error message with links at the bottom of the page.

  4. Click the Show Complete Compilation Source link to display the autogenerated code for your control.

User Controls in Visual Studio .NET

Visual Studio .NET uses the code-behind model for user controls, which is similar to the code-behind model for pages that we described in Chapter 2. In this model, the declarative syntax is contained in an .ascx file, while the server-side code exists in a separate file in a class (called the code-behind class ) that derives from System.Web.UI.UserControl . The Web Forms Designer generates the code-behind class and precompiles all of the Web application's page and user control code-behind classes into an assembly. The designer creates the assembly in the Web application's bin directory.

If you develop a user control similar to RequiredTextField (shown in Listing 4-2) using the Web User Control template in Visual Studio .NET, the code for a designer-generated code-behind class will be similar to that shown in Listing 4-7.

Listing 4-7 MyVSUserControl.ascx.cs
 namespaceBookWeb.Chapter4.UserControls { usingSystem; usingSystem.Data; usingSystem.Drawing; usingSystem.Web; usingSystem.Web.UI.WebControls; usingSystem.Web.UI.HtmlControls; ///<summary> ///Thecode-behindclassforMyVSUserControl.ascx. ///</summary> publicabstractclassMyVSUserControl:System.Web.UI.UserControl { protectedTextBoxentryTextBox; protectedRequiredFieldValidatorrequiredFieldValidator1; publicstringText { get { returnentryTextBox.Text; } set { entryTextBox.Text=value; } } privatevoidPage_Load(objectsender,System.EventArgse) { //Putusercodetoinitializethepagehere. } #regionWebFormDesignergeneratedcode overrideprotectedvoidOnInit(EventArgse) { // //CODEGEN:ThiscallisrequiredbytheASP.NET //WebFormDesigner. // 
 InitializeComponent(); base.OnInit(e); } ///Requiredmethodfordesignersupport;donotmodify ///thecontentsofthismethodwiththecodeeditor. ///</summary> privatevoidInitializeComponent() { this.Load+=newSystem.EventHandler(this.Page_Load); } #endregion } } 

The declarative portion of the control is in an .ascx file, shown in Listing 4-8.

Listing 4-8 MyVSUserControl.ascx
  <%@ControlLanguage="c#"AutoEventWireup="false" ClassName="VSRequiredTextField"Codebehind="MyVSUserControl.ascx.cs" Inherits="BookWeb.Chapter4.UserControls.MyVSUserControl"%>  <asp:TextBoxid="entryTextBox"runat="server"/> &nbsp; <asp:RequiredFieldValidatorid="requiredFieldValidator1"runat="server" ErrorMessage="(required)"ControlToValidate="entryTextBox" ToolTip="Youmustenteravalue."/> &nbsp; 

The Control directive in the code-behind case is slightly different from that in the embedded script case. The Inherits attribute specifies the name of the code-behind class, and the Codebehind attribute specifies the location of the code-behind file.

Although the code-behind class is precompiled by the designer, the user control still must go through the process of dynamic code generation and compilation. The real user control is the class that is autogenerated by the page parser by deriving from the code-behind class and adding code to correspond to the declarative syntax in the .ascx file.

If you use the code-behind model for your pages, you should also use it for your user controls. If you mix the two models, you might encounter errors. For example, you cannot programmatically access members of a user control that has an embedded script block from the code-behind class of the containing .aspx page. Such access is possible, however, if you define a code-behind class for the user control.

Listings 4-9 and 4-10 show the declarative and code-behind files for a designer-generated page that uses MyVSUserControl . This page is similar in behavior to the RequiredTextFieldTest.aspx page in Listing 4-3.

Listing 4-9 MyVSUserControlTest.aspx
 <%@Pagelanguage="c#"Codebehind="MyVSUserControlTest.aspx.cs" AutoEventWireup="false"Inherits="BookWeb.Chapter4.MyVSUserTest"%> <%@RegisterTagPrefix="uc1"TagName="MyVSUser" src="UserControls/MyVSUserControl.ascx"%> <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> <HTML> <HEAD> <title>MyVSUserTest</title> <metaname="GENERATOR"Content="MicrosoftVisualStudio7.0"> <metaname="CODE_LANGUAGE"Content="C#"> <metaname="vs_defaultClientScript"content="JavaScript"> <metaname="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body> <formid="MyVSUserTest"method="post"runat="server"> <p> ThispageusestheMyVSUserControlusercontrol. </p> <p> Enteravalue: </p> <uc1:MyVSUserid="MyVSUser1"runat="server"></uc1:MyVSUser> <p> <asp:Buttonid="okButton"runat="server"Text="OK" Width="75px"></asp:Button> </p> <p> <asp:Labelid="infoLabel"runat="server"></asp:Label> </p> </form> </body> </HTML> 
Listing 4-10 MyVSUserControlTest.aspx.cs
 usingSystem; usingSystem.Collections; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Web; usingSystem.Web.SessionState; 
 usingSystem.Web.UI; usingSystem.Web.UI.WebControls; usingSystem.Web.UI.HtmlControls; namespaceBookWeb.Chapter4 { ///<summary> ///SummarydescriptionforMyVSUserControlTest. ///</summary> publicclassMyVSUserTest:System.Web.UI.Page { protectedSystem.Web.UI.WebControls.ButtonokButton; protectedSystem.Web.UI.WebControls.LabelinfoLabel;  protectedBookWeb.Chapter4.UserControls.MyVSUserControl MyVSUser1;  privatevoidPage_Load(objectsender,System.EventArgse) { //Putusercodetoinitializethepagehere. } #regionWebFormDesignergeneratedcode overrideprotectedvoidOnInit(EventArgse) { // //CODEGEN:ThiscallisrequiredbytheASP.NET //WebFormDesigner. // InitializeComponent(); base.OnInit(e); } ///<summary> ///Requiredmethodfordesignersupport;donotmodify ///thecontentsofthismethodwiththecodeeditor. ///</summary> privatevoidInitializeComponent() { this.okButton.Click+=new System.EventHandler(this.okButton_Click); this.Load+=newSystem.EventHandler(this.Page_Load); } #endregion 
 privatevoidokButton_Click(objectsender,System.EventArgse) { infoLabel.Text="Youentered'"+  MyVSUser1.Text  +"'."; } } } 

The main item to note in this example is that if you need to access the user control in the code-behind class of your page ”for example, in an event handler ”you must declare a public or protected field in the code-behind class of the page that corresponds to the user control instance on the page. The designer will not generate this field for you. The name of the field must match the ID assigned to the user control in the .aspx page. The code that declares and accesses this field is boldface in Listing 4-10.



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