1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 127 ppt

10 123 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Nội dung

Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1221 Chapter 26: User and Server Controls Listing 26-18: Sample ASP.NET skin <%@ Register Assembly="WebControlLibrary1" Namespace="WebControlLibrary1" TagPrefix="cc1" %> <cc1:webcustomcontrol1 BackColor="Green" runat="server" /> By default, ASP.NET allows all control properties to be defined in the skin file, but obviously this is not always appropriate. Most exposed properties are non-UI related; therefore, you do not apply a theme to them. By setting the Themeable attribute to False on each of these properties, you prevent the application of a theme. Listing 26-19 shows how to do this in your control by disabling themes on the Text property. Listing 26-19: Disabling theme support on a control property VB <Bindable(True), Category("Appearance"), DefaultValue(""), _ Localizable(True), Themeable(False)> _ Property Text() As String Get Dim s As String = CStr(ViewState("Text")) If s Is Nothing Then Return "[" + Me.ID + "]" Else Return s End If End Get Set(ByVal Value As String) ViewState("Text") = Value End Set End Property C# [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] [Themeable(false)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? "["+ this.ID + "]": s); } set { ViewState["Text"] = value; } } Now, if a developer attempts to define this property in his skin file, he receives a compiler error when the page is executed. 1221 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1222 Chapter 26: User and Server Controls Adding Client-Side Features Although the capability to render and style HTML is quite powerful by itself, other resources can be sent to the client, such as client-side scripts, images, and resource strings. ASP.NET 3.5 provides you with some powerful new tools for using client-side scripts in your server controls and retrieving other resources to the client along with the HTML your control emits. Additionally, ASP.NET now includes an entire model that allows you to make asynchronous callbacks from your Web page to the server. Emitting Client-Side Script Having your control emit client-side script such as VBScript or JavaScript enables you to add powerful client-side functionality to your control. Client-side scripting languages take advantage of the client’s browser to create more flexible and easy-to-use controls. Although ASP.NET 1.0 provided some simple methods to emit client-side script to the browser, ASP.NET has since enhanced these capabilities and now provides a wide variety of methods for emitting client-side script that you can use to control where and how your script is rendered. If you have already used ASP.NET 1.0 to render client-side script to the client, you are probably famil- iar with a few methods such as the Page.RegisterClientScriptBlock and the Page.RegisterStartup Script methods. Since ASP.NET 2.0, these classes have been deprecated. Instead, ASP.NET now uses the ClientScriptManager class, which you can access using Page.ClientScript . This class exposes various static client-script rendering methods that you can use to render client-side script. Listing 26-20 demonstrates how you can use the RegisterStartupScriptMethod method to render JavaScript to the client. This listing adds the code into the OnPreRender method, rather than into the Render method used in previous samples. This method allows every control to inform the page about the client-side script it needs to render. After the Render method is called, the page is able to render all the client-side script it collected during the OnPreRender method. If you call the client-side script reg- istration methods in the Render method, the page has already completed a portion of its rendering before your client-side script can render itself. Listing 26-20: Rendering a client-side script to the browser VB Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) Page.ClientScript.RegisterStartupScript(GetType(Page), _ "ControlFocus", "document.getElementById("’ & Me.ClientID & _ "_i" & "’).focus();", _ True) End Sub C# protected override void OnPreRender(EventArgs e) { Page.ClientScript.RegisterStartupScript( typeof(Page), "ControlFocus","document.getElementById("’ + this.ClientID + "_i" + "’).focus();", true); } In this listing, the code emits client-side script to automatically move the control focus to the TextBox control when the Web page loads. When you use the RegisterStartupScript method, notice that it now 1222 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1223 Chapter 26: User and Server Controls includes an overload that lets you specify if the method should render surrounding script tags. This can be handy if you are rendering more than one script to the page. Also notice that the method requires a key parameter. This parameter is used to uniquely identify the script block; if you are registering more than one script block in the Web page, make sure that each block is supplied a unique key. You can use the IsStartupScriptRegistered method and the key to determine if a particular script block has been previously registered on the client using the RegisterStatupScript method. When you execute the page in the browser, notice that the focus is automatically placed into a text box. If you look at the source code for the Web page, you should see that the JavaScript was written to the bottom of the page, as shown in Figure 26-11. Figure 26-11 If you want the script to be rendered to the top of the page, you use the RegisterClientScriptBlock method that emits the script block immediately after the opening < form > element. Keep in mind that the browser parses the Web page from top to bottom, so if you emit client-side script at the top of the page that is not contained in a function, any references in that code to HTML elements further down the page will fail. The browser has not parsed that portion of the page yet. 1223 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1224 Chapter 26: User and Server Controls Being able to render script that automatically executes when the page loads is nice, but it is more likely that you will want the code to execute based on an event fired from an HTML element on your page, such as the Click, Focus, or Blur events. In order to do this, you add an attribute to the HTML element you want the event to fire from. Listing 26-21 shows you how you can modify your control’s Render and PreRender methods to add this attribute. Listing 26-21: Using client-side script and event attributes to validate data VB Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter) output.RenderBeginTag(HtmlTextWriterTag.Div) output.AddAttribute(HtmlTextWriterAttribute.Type, "text") output.AddAttribute(HtmlTextWriterAttribute.Id, Me.ClientID & "_i") output.AddAttribute(HtmlTextWriterAttribute.Name, Me.ClientID & "_i") output.AddAttribute(HtmlTextWriterAttribute.Value, Me.Text) output.AddAttribute("OnBlur", "ValidateText(this)") output.RenderBeginTag(HtmlTextWriterTag.Input) output.RenderEndTag() output.RenderEndTag() End Sub Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) Page.ClientScript.RegisterStartupScript(GetType(Page), _ "ControlFocus", "document.getElementById("’ & Me.ClientID & _ "_i" & "’).focus();", _ True) Page.ClientScript.RegisterClientScriptBlock( _ GetType(Page), _ "ValidateControl", _ "function ValidateText() {" & _ "if (ctl.value==") {" & _ "alert(’Please enter a value.’);ctl.focus();} " & _ "}", _ True) End Sub C# protected override void RenderContents(HtmlTextWriter output) { output.RenderBeginTag(HtmlTextWriterTag.Div); output.AddAttribute(HtmlTextWriterAttribute.Type, "text"); output.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_i"); output.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID + "_i"); output.AddAttribute(HtmlTextWriterAttribute.Value, this.Text); output.AddAttribute("OnBlur", "ValidateText(this)"); output.RenderBeginTag(HtmlTextWriterTag.Input); output.RenderEndTag(); 1224 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1225 Chapter 26: User and Server Controls output.RenderEndTag(); } protected override void OnPreRender(EventArgs e) { Page.ClientScript.RegisterStartupScript( typeof(Page), "ControlFocus","document.getElementById("’ + this.ClientID + "_i" + "’).focus();", true); Page.ClientScript.RegisterClientScriptBlock( typeof(Page), "ValidateControl", "function ValidateText(ctl) {" + "if (ctl.value==") {" + "alert(’Please enter a value.’);ctl.focus();} " + "}", true); } As you can see, the TextBox control is modified to check for an empty string. We have also included an attribute that adds the JavaScript OnBlur event to the text box. The OnBlur event fires when the control loses focus. When this happens, the client-side ValidateText method is executed, which we rendered to the client using RegisterClientScriptBlock . The rendered HTML is shown in Figure 26-12. Embedding JavaScript in the page is powerful, but if you are writing large amounts of client-side code, you might want to consider storing the JavaScript in an external file. You can include this file in your HTML by using the RegisterClientScriptInclude method. This method renders a script tag using the URL you provide to it as the value of its src element. <script src="[url]" type="text/javascript"></script> Listing 26-22 shows how you can modify the validation added to the TextBox control in Listing 26-20; but this time, the JavaScript validation function is stored in an external file. Listing 26-22: Adding client-side script include files to a Web page VB Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) Page.ClientScript.RegisterClientScriptInclude( _ "UtilityFunctions", "JScript.js") Page.ClientScript.RegisterStartupScript(GetType(Page), _ "ControlFocus", "document.getElementById("’ & Me.ClientID & _ "_i" & "’).focus();", _ True) End Sub C# protected override void OnPreRender(EventArgs e) { Continued 1225 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1226 Chapter 26: User and Server Controls Page.ClientScript.RegisterClientScriptInclude( "UtilityFunctions", "JScript.js"); Page.ClientScript.RegisterStartupScript( typeof(Page), "ControlFocus","document.getElementById("’ + this.ClientID + "_i" + "’).focus();", true); } Figure 26-12 You have modified the OnPreRender event to register a client-side script file include, which contains the ValidateText function. You need to add a JScript file to the project and create the ValidateText function, as shown in Listing 26-23. 1226 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1227 Chapter 26: User and Server Controls Listing 26-23: The validation JavaScript contained in the Jscript file // JScript File function ValidateText(ctl) { if (ctl.value==") { alert(’Please enter a value.’); ctl.focus(); } } The ClientScriptManager also provides methods for registering hidden HTML fields and adding script functions to the OnSubmit event. Accessing Embedded Resources A great way to distribute application resources like JavaScript files, images, or resource files is to embed them directly into the compiled assembly. While this was possible in ASP.NET 1.0, it was very difficult to access these resources as part of the page request process. ASP.NET 2.0 solved this problem by including the RegisterClientScriptResource method as part of the ClientScriptManager. This method makes it possible for your Web pages to retrieve stored resources — like JavaScript files — from the compiled assembly at runtime. It works by using an HttpHandler to retrieve the requested resource from the assembly and return it to the client. The RegisterClientScriptResource method emits a < script > block whose src value points to this HttpHandler: <script language="javascript" src="WebResource.axd?a=s&r=WebUIValidation.js&t=631944362841472848" type="text/javascript"> </script> As you can see, the WebResource.axd handler is used to return the resource — in this case, the JavaScript file. You can use this method to retrieve any resource stored in the assembly, such as images or localized content strings from resource files. Asynchronous Callbacks Finally, ASP.NET also includes a convenient mechanism for enabling basic AJAX behavior, or client-side callbacks, in a server control. Client-side callbacks enable you to take advantage of the XmlHttp components found in most modern browsers to communicate with the server without actually performing a complete postback. Figure 26-13 shows how client-side callbacks work in the ASP.NET Framework. In order to enable callbacks in your server control, you implement the System.Web.UI.ICallBackEvent Hander interface. This interface requires you to implement two methods, the RaiseCallbackEvent method and the GetCallbackResult method . These are the server-side events that fire when the client executes the callback. After you implement the interface, you want to tie your client-side events back to the server. You do this by using the Page.ClientScript.GetCallbackEventReference method. 1227 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1228 Chapter 26: User and Server Controls This method allows you to specify the two client-side functions: one to serve as the callback handler and one to serve as an error handler. Listing 26-24 demonstrates how you can modify the TextBox con- trol’s Render methods and add the RaiseCallBackEvent method to use callbacks to perform validation. Using JavaScript, the browser creates an instance of the MSXML ActiveX control The MSXML ActiveX control makes a request to the server JavaScript handles the Callback method The Internet JavaScript handles the ErrorCallback method The request raises the ICallbackEventHandler method RaiseCallbackEvent on the server Method returns a string, or thrown an exception Figure 26-13 Listing 26-24: Adding an asynchronous callback to validate data VB Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter) output.RenderBeginTag(HtmlTextWriterTag.Div) output.AddAttribute(HtmlTextWriterAttribute.Type, "text") output.AddAttribute(HtmlTextWriterAttribute.Id, Me.ClientID & "_i") output.AddAttribute(HtmlTextWriterAttribute.Name, Me.ClientID & "_i") output.AddAttribute(HtmlTextWriterAttribute.Value, Me.Text) output.AddAttribute("OnBlur", "ClientCallback();") Me.AddAttributesToRender(output) output.RenderBeginTag(HtmlTextWriterTag.Input) output.RenderEndTag() output.RenderEndTag() End Sub Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) Page.ClientScript.RegisterStartupScript(GetType(Page), _ 1228 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1229 Chapter 26: User and Server Controls "ControlFocus", "document.getElementById("’ & _ Me.ClientID & "_i" & "’).focus();", _ True) Page.ClientScript.RegisterStartupScript( _ GetType(Page), "ClientCallback", _ "function ClientCallback() {" & _ "args=document.getElementById("’ & Me.ClientID & "_i" & "’).value;" & _ Page.ClientScript.GetCallbackEventReference(Me, "args", _ "CallbackHandler", Nothing, "ErrorHandler", True) + "{", _ True) End Sub Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _ Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent Dim result As Int32 If (Not Int32.TryParse(eventArgument, result)) Then Throw New Exception("The method or operation is not implemented.") End If End Sub Public Function GetCallbackResult() As String _ Implements System.Web.UI.ICallBackEventHandler.GetCallbackResult Return "Valid Data" End Function C# protected override void RenderContents(HtmlTextWriter output) { output.RenderBeginTag(HtmlTextWriterTag.Div); output.AddAttribute(HtmlTextWriterAttribute.Type, "text"); output.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_i"); output.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID + "_i"); output.AddAttribute(HtmlTextWriterAttribute.Value, this.Text); output.AddAttribute("OnBlur", "ClientCallback();"); this.AddAttributesToRender(output); output.RenderBeginTag(HtmlTextWriterTag.Input); output.RenderEndTag(); output.RenderEndTag(); } protected override void OnPreRender(EventArgs e) { Page.ClientScript.RegisterStartupScript( typeof(Page), "ControlFocus","document.getElementById("’ + this.ClientID + "_i" + "’).focus();", true); 1229 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1230 Chapter 26: User and Server Controls Page.ClientScript.RegisterStartupScript( typeof(Page), "ClientCallback", "function ClientCallback() {" + "args=document.getElementById("’ + this.ClientID + "_i" + "’).value;" + Page.ClientScript.GetCallbackEventReference(this, "args", "CallbackHandler", null,"ErrorHandler",true) + "{", true); } #region ICallbackEventHandler Members public void RaiseCallbackEvent(string eventArgument) { int result; if (!Int32.TryParse(eventArgument,out result) ) throw new Exception("The method or operation is not implemented."); } public string GetCallbackResult() { return "Valid Data"; } #endregion As you can see, the OnBlur attribute has again been modified, this time by simply calling the Client- Callback method. This method is created and rendered during the PreRender event. The main purpose of this event is to populate the client-side args variable and call the client-side callback method. You are using the GetCallbackEventReference method to generate the client-side script that actually initiates the callback. The parameters passed to the method indicate which control is initiating the call- back, the names of the client-side callback method, and the name of the callback method parameters. The following table provides more details on the GetCallbackEventReference arguments. Parameter Description Control Server control that initiates the callback. Argument Client-side variable used to pass arguments to the server-side event handler. ClientCallback Client-side function serving as the Callback method. This method fires when the server-side processing has completed successfully. Context Client-side variable that gets passed directly to the receiving client-side function. The context does not get passed to the server. ClientErrorCallback Client-side function serving as the Callback error-handler method. This method fires when the server-side processing encounters an error. In the code, two client-side methods are called: CallbackHandler and ErrorHandler , respectively. The two method parameters are args and ctx . In addition to the server control code changes, the two client-side callback methods have been added to the JavaScript file. Listing 26-25 shows these new functions. 1230 . the Page.RegisterClientScriptBlock and the Page.RegisterStartup Script methods. Since ASP. NET 2.0, these classes have been deprecated. Instead, ASP. NET now uses the ClientScriptManager class, which you can access using Page.ClientScript directly into the compiled assembly. While this was possible in ASP. NET 1.0, it was very difficult to access these resources as part of the page request process. ASP. NET 2.0 solved this problem by including the RegisterClientScriptResource method. more flexible and easy-to-use controls. Although ASP. NET 1.0 provided some simple methods to emit client-side script to the browser, ASP. NET has since enhanced these capabilities and now provides

Ngày đăng: 05/07/2014, 19:20

TỪ KHÓA LIÊN QUAN