Tài liệu ASP.NET 1.1 Insider Solutions- P8 pdf

50 890 0
Tài liệu ASP.NET 1.1 Insider Solutions- P8 pdf

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

The problem you have with Mozilla 1.5 and the SpinBox control is also related to the speci- fications of CSS2 not being totally compre- hensive. Recall that the structure generated for the SpinBox control (see Figure 8.13) is a root <span> element that is relatively posi- tioned. The contained TextBox control is not positioned (it simply appears in the flow of the page within the <span> control). However, the two ImageButton controls carry the position:absolute selectors so that they will be located at the right side of the TextBox control. 8 Building Adaptive Controls 338 The Drop-Down Lists in Internet Explorer Interestingly, in Internet Explorer 5.5, the drop-down lists open on top of the text boxes, but not always on top of each other in the correct order—depending on the order in which they are opened. Textbox ImageButtons position:absolute <span> element position:relative FIGURE 8.13 The structure of the standard SpinBox control. What happens is that the ImageButton controls (which are rendered as <input type=”image”> elements in the page) are removed from the flow of the page by the position:absolute selectors. This means that the <span> element is only sized to contain the TextBox control, so the two ImageButton controls lie outside the <span> element in terms of location—even though they are still child controls. Internet Explorer and Opera take into account the control hierarchy, and the buttons work fine. However, Mozilla does not consider the buttons to be part of the rendered page as far as the mouse pointer is concerned, and it ignores mouse clicks on them. But if you place the cursor on the text box and press the Tab key, you do in fact move the focus to them and can click them by pressing the Spacebar. Creating an Alternative Structure for the SpinBox Control One solution for the various problems with the SpinBox control is to offer an alternative struc- ture for the controls that provides wider support for older browsers. The obvious approach is to use an HTML table to locate the TextBox and ImageButton controls. But this leads to another problem. The reason you used a <span> element in the first place was so that the control could be used like a TextBox control or other standard controls within the flow layout of the page. For example, the user should be able to place a text caption to the left and more content after it, without causing the caption or the following content to wrap to a new line. If you use an HTML table to locate the constituent controls, it will cause preceding and following content to wrap, forcing the user to insert the whole lot into an HTML table (or use absolute positioning) to get the layout desired. Another possibility is to use a <div> element as the root control for the SpinBox control, but this has the same problem as using an HTML table. In the end, this example uses the HTML table but adds an extra cell to the left, where you insert a user-supplied value for the caption (see Figure 8.14). It’s not ideal because preceding and following content will still wrap, but at least 11 0672326744 CH08 5/4/04 12:24 PM Page 338 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 339 Making the SpinBox Control Adaptive the caption will appear in the correct position. And it seems to be the only solution for older browsers. TextboxCaption ImageButtons with <br /> HTML <table> element HTML <td> table cells FIGURE 8.14 The structure of the adaptive SpinBox control for older browsers. To maintain the interface and behavior of the control across all browser types, you need to support the caption in more recent browsers that work with the up-level version of the control. You can expose the caption as a property of the control, and if the user sets this property, he or she will expect to see it appear in all browsers. Figure 8.15 shows the updated structure of the SpinBox control for these newer browser types. TextboxCaption ImageButtons position:absolute <span> element <span> element position:relative FIGURE 8.15 The structure of the adaptive SpinBox control for more recent browsers. Adaptability Changes to the SpinBox Control Class The following sections briefly review the changes required in the SpinBox control to implement the dual behavior for up-level and down-level clients. When you look at the CreateChildControls method, you’ll see how you decide what output to send to each type of browser. Changes to the Private and Public Declarations You need to make a couple minor changes to the variable and property declarations of the SpinBox control. You must import the System.Web.UI.HtmlControls namespace because you’re using the HtmlGenericControl class that it defines to create the nested <span> element for the up- level version of the control. You also use a different class name this time ( AdaptiveSpinBox ). You can add an enumeration to the control to define the “modes” it can run in. This allows a user to specify, for example, down-level behavior, even if their browser supports the up-level features: ‘ enumeration of target browser types Public Enum ClientTargetType AutoDetect = 0 11 0672326744 CH08 5/4/04 12:24 PM Page 339 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. UpLevel = 1 DownLevel = 2 End Enum You also need a few more internal variables and the property declarations for the two new prop- erties Caption and ClientTarget . The first two internal variables, _usetable and _usecss2 , default to False and are used in other routines within the control to manage the type of output you send to the client. Notice that the ClientTarget property is read-only and is defined as a value from the ClientTargetType enumeration. The internal _client variable that shadows the value of the ClientTarget property sets the default to AutoDetect (see Listing 8.20). LISTING 8.20 Registering for Postbacks in the Init Event Private _usetable As Boolean = True Private _usecss2 As Boolean = False Private _caption As String = “” Private _client As ClientTargetType = ClientTargetType.AutoDetect Public Property Caption As String Get Return _caption End Get Set _caption = value End Set End Property Public WriteOnly Property ClientTarget As ClientTargetType Set _client = value End Set End Property Changes to the CreateChildControls Method The largest number of changes occur in the CreateChildControls method, where you generate the control tree for the SpinBox control. In it, you add code that uses the ASP.NET BrowserCapabilities object (which you met in Chapter 7) to detect the current browser type and decide what features it supports. Listing 8.21 assumes that the client is a down-level device and then checks whether it supports JavaScript. If it does not, there’s no point in generating the interactive version of the control that uses CSS2 scripting. If JavaScript is supported, you can use the browser name and major version number to decide what to do next. Notice that for Internet Explorer 5 and higher, and for Opera 6 and higher, you specify that it’s an up-level device and that you’ll use CSS2 script- ing, but you will not generate an HTML table. 8 Building Adaptive Controls 340 11 0672326744 CH08 5/4/04 12:24 PM Page 340 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 341 Making the SpinBox Control Adaptive LISTING 8.21 Detecting the Browser Type and Capabilities ‘ check if the current browser supports features ‘ required for “smart” operation and if user specified ‘ the mode they want (Version6 or Downlevel) If _client <> ClientTargetType.DownLevel Then ‘ start by assuming DownLevel _client = ClientTargetType.DownLevel ‘ get reference to BrowserCapabilities object Dim oBrowser As HttpBrowserCapabilities = Context.Request.Browser ‘ must support client-side JavaScript If oBrowser(“JavaScript”) = True Then ‘ get browser type and version Dim sUAType As String = oBrowser(“Browser”) Dim sUAVer As String = oBrowser(“MajorVersion”) ‘ see if the current client is IE5 or above If (sUAType = “IE”) And (sUAVer >= 5) Then _client = ClientTargetType.UpLevel _usetable = False _usecss2 = True End If ‘ see if the current client is Netscape 6.0/Mozilla 1.0 If (sUAType = “Netscape”) And (sUAVer >= 5) Then _client = ClientTargetType.UpLevel _usetable = True _usecss2 = True End If ‘ see if the current client is Opera 6.0 If (sUAType = “Opera” And sUAVer >= 6) Then _client = ClientTargetType.UpLevel _usetable = False _usecss2 = True End If End If End If 11 0672326744 CH08 5/4/04 12:24 PM Page 341 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. ‘ save current value of _client in viewstate ViewState(sCID & “target”) = _client.ToString() ‘ display detected client type value in Trace Context.Trace.Write(“CreateChildControls:” & Me.UniqueID, _ “Saved target ‘“ & _client.ToString() & “‘ in viewstate”) The odd ones out as far as browsers go are Netscape and Mozilla. If the current browser is Netscape or Mozilla, with a version number of 5 or higher (which actually equates to Netscape 6.0 and Mozilla 1.0), it is up-level, and you can use CSS2 scripting. However, due to the problem with the <span> element and the absolute-positioned ImageButton controls shown earlier, you have to generate the structure of the control as an HTML table. It will still be interactive because you’ll inject the client-side script and add the client-side event handlers. You also need to save the client target value (the value of the _client variable) in the viewstate of the page so that you can extract it next time. This is a property of the control that users will expect to be maintained across postbacks. If they have set it to DownLevel , they won’t expect the code to perform the detection again after each postback and reset the value. Creating Browser-Specific Output Now you can build the control tree needed. To make it easier to manage, the tasks required to create the control output have been separated into three routines: n CreateCSS2Controls —This routine creates basically the same control tree as the standard version of the SpinBox control you saw earlier in this chapter. The only differences are that the root <span> control is no longer relative positioned, and it contains the caption text and the nested <span> control that is relative positioned (refer to Figure 8.14 for more details). n CreateHTMLTable —This routine creates the control structure shown in Figure 8.13. This is the HTML table version, consisting of three cells that contain the caption, the text box, and the two image buttons. One interesting point here is that you have to use a LiteralControl instance to create the <br /> element that is required to wrap the second ImageButton under the first one in the right-hand cell. If you use an HtmlGenericControl instance, you actually get the string “<br></br>” , which causes most browsers to insert two line breaks. n InjectClientScript —This routine uses exactly the same code that is used in the standard version of the SpinBox control to generate the <script> element that references the client- side script file for the control (which must be located in the /aspnet_client/custom/ folder of the Web site). It also adds the client-side event handler attributes to the TextBox control and the two ImageButton controls. We don’t describe the three routines in detail here because they are generally repetitive and do not introduce anything new to the discussion. You can view the source code to see these 8 Building Adaptive Controls 342 LISTING 8.21 Continued 11 0672326744 CH08 5/4/04 12:24 PM Page 342 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 343 Making the SpinBox Control Adaptive routines. (Remember that each sample contains a [view source] link at the foot of the page. See www.daveandal.net/books/6744/ .) Listing 8.22 shows the next section of the CreateChildControls method, where the _usetable and _usecss2 variables are used to decide which of the three routines just described are executed. The result is that the control generates output that is suitable for the current browser and provides the best possible support it can, depending on the features of that browser. Next, although not shown in Listing 8.22, the values of the properties are displayed in the Trace object in exactly the same way as in the standard SpinBox control example. LISTING 8.22 Creating the Appropriate Control Tree ‘ now ready to create the appropriate set of controls If _usetable = False Then ‘ serving to version-6 client, use absolute positioning ‘ (but not for Netscape 6.x or Mozilla 1.x) CreateCSS2Controls() Else ‘ serving to down-level client, create HTML table ‘ (including Netscape 6.x or Mozilla 1.x) CreateHTMLTable() End If If _usecss2 = True Then ‘ serving to client that supports CSS2 so inject script InjectClientScript() End If Changes to the LoadPostData Method For the SpinBox control example, the only other changes required to provide behavior that adapts to different clients are to the code in the LoadPostData routine. You have to extract the value from the postback and compare it to the existing value of the control, as stored in the viewstate of the page. If these two values differ from one another, you raise the ValueChanged event. If they are the same, you use the existing value from the viewstate to populate the control. The issue with the adaptive control is that, in down-level clients, clicking the up and down buttons does not automatically change the value in the text box—because there is no client-side 11 0672326744 CH08 5/4/04 12:24 PM Page 343 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. script to do that. Such clicks will always cause postbacks to the server. So you have to check for a click on either of the two ImageButton controls, and you have to see if the value in the text box has been changed. Listing 8.23 shows the LoadPostData method. After it extracts the value for the text box from the postback collection, it gets the value when the page was originally created from the viewstate and the value of the client target type. (Both of these values are saved in the viewstate in the CreateChildControls method.) LISTING 8.23 The LoadPostData Method in the Adaptive SpinBox Control Overridable Function LoadPostData(key As String, _ vals As NameValueCollection) _ As Boolean _ Implements IPostBackDataHandler.LoadPostData ‘ occurs when data in postback is available to control ‘ get value of control from postback collection Dim sNewValue As String = vals(key & “_textbox”) Context.Trace.Write(“LoadPostData:” & key, _ “Loaded postback value ‘“ & sNewValue & “‘ from Request”) ‘ get value from viewstate - i.e. when page was last created Dim sExistingValue As String = ViewState(key & “_textbox”) Context.Trace.Write(“LoadPostData:” & key, _ “Loaded existing value ‘“ & sExistingValue & “‘ from viewstate”) ‘ get client target type from viewstate Dim sClientType As String = ViewState(key & “_target”) Context.Trace.Write(“LoadPostData:” & key, _ “Loaded target ‘“ & sClientType & “‘ from viewstate”) If (sClientType = ClientTargetType.UpLevel.ToString()) _ Or (sNewValue <> sExistingValue) Then ‘ either client type is “UpLevel” and value was ‘ incremented by client-side script, or user typed ‘ new value in Textbox in “DownLevel” client If sNewValue <> sExistingValue Then ‘ value in control has been changed by user ‘ set internal member to posted value and return True ‘ so that PostDataChangedEvent will be raised _text = sNewValue 8 Building Adaptive Controls 344 11 0672326744 CH08 5/4/04 12:24 PM Page 344 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 345 Making the SpinBox Control Adaptive Return True Else ‘ value in control has not changed ‘ set internal member to viewstate value and write message ‘ return False because no need to raise ValueChanged event _text = sExistingValue Return False End If Else ‘ client type may be “DownLevel” and value was not incremented ‘ so check if “up” or “down” button caused the postback If vals(key & “_imageup.x”) <> “” Then ‘ “up” image button was clicked so increment value ‘ new value will be checked in CreateChildControls event ‘ to ensure its within maximum and minimum value limits ‘ use Try Catch in case viewstate empty or text not a number Try _text = CType(Int32.Parse(sExistingValue) + _increment, _ String) Context.Trace.Write(“LoadPostData:” & key, _ “Incremented value to ‘“ & _text) Catch Context.Trace.Write(“LoadPostData:” & key, _ “Error reading viewstate: “ & sExistingValue) End Try ‘ return True so that PostDataChangedEvent will be raised Return True End If If vals(key & “_imagedown.x”) <> “” Then ‘ “down” image button was clicked so decrement value Try _text = CType(Int32.Parse(sExistingValue) - _increment, _ String) Context.Trace.Write(“LoadPostData:” & key, _ “Decremented value to ‘“ & _text) LISTING 8.23 Continued 11 0672326744 CH08 5/4/04 12:24 PM Page 345 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Catch Context.Trace.Write(“LoadPostData:” & key, _ “Error reading viewstate: “ & sExistingValue) End Try ‘ return True so that PostDataChangedEvent will be raised Return True End If End If End Function Then you can see if this is an up-level client or if the value of the text box has been changed. Remember that for down-level clients, the user could have typed a new value into the text box and then submitted the page. If the value has changed, you save it in the internal _text variable and return True to indicate that you want the page framework to call the RaisePostBackDataChangedEvent method, where you’ll raise the ValueChanged event. If the text box value has not changed, you must check whether the user submitted the page from a down-level client by clicking the up or down button. You can detect whether one of these buttons was clicked by looking for its value in the postback collection. ImageButton controls send the x and y coordinates of the mouse pointer within the image when they are clicked, or they send zero for both coordinates when the spacebar is used to click the image. All you have to do is try to increment or decrement the current value (stored in the _text variable) by the current value of the Increment property (stored in the _increment variable) and return True to cause the ValueChanged event to be raised. If you turn on tracing for the page and initiate a postback by clicking the up or down button, you’ll see the messages that the code writes to the Trace object. In Figure 8.16, you can see the values in the postback collection and the viewstate being loaded, and you can see the ValueChanged event being raised. You can also see the points at which the value and the client target type are saved back into the viewstate and the values of the other properties of the control. Testing and Using an Adaptive SpinBox Control The demonstration page for the adaptive SpinBox control that is provided with the samples for this book is just about identical to the one shown for the standard SpinBox control earlier in this chapter. The page allows the new Caption property to be set and shows that caption next to the control. Of course, the classname is different this time, so the Register directive looks like this: <%@ Register TagPrefix=”ahh” Namespace=”Stonebroom” Assembly=”adaptive-spinbox” %> 8 Building Adaptive Controls 346 LISTING 8.23 Continued 11 0672326744 CH08 5/4/04 12:24 PM Page 346 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 347 Making the SpinBox Control Adaptive The adaptive version of the SpinBox control looks and behaves the same in Internet Explorer and Opera as the standard version does. However, it now works in other browsers as well. For example, Figure 8.17 shows it in Mozilla, where the up and down buttons now work as expected. FIGURE 8.16 The trace output from the adap- tive SpinBox control following a postback. FIGURE 8.17 The adaptive SpinBox control in Mozilla 1.5. Figure 8.18 shows the adaptive SpinBox control demonstration page in Netscape Navigator 4.5. The original version of the control fails to show the text box or position the up and down buttons correctly in this browser—but the adaptive version works as it should. 11 0672326744 CH08 5/4/04 12:24 PM Page 347 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... login, and so on The problem you face is how to create this structure so that you gain consistency across pages without losing the ease of development that ASP.NET brings What you want is the master pages scenario that ASP.NET 2.0 provides, but for ASP.NET 1.1 Master pages give you the ability to use some sort of template to define the content that should appear on all pages, and at runtime this content... master page defined 4 If no Content control is found in the content page, the default content from the ContentPlaceHolder control is used This process is easy to re-create in ASP.NET 1.1, with one major exception: It’s not part of the ASP.NET Page Framework Therefore, you can’t use a MasterPageFile attribute on the page directive, and you don’t have automatic support for master pages However, you can write... Framework 1.1 Configuration This useful program provides access to many features of the NET Framework, including the GAC (shown as Assembly Cache in the left tree-view window) To add an assembly, you simply right-click the Assembly Cache entry in the left window of the NET Configuration tool and select Add; then you locate the assembly In Figure 8.20, the assembly DLL has been copied into the Framework\v1.1.4322... But then I’m quite dull, so that’s only to be expected Page Footer Page Header Menu Page Header Menu 354 A product description goes here A product description goes here Page Footer Unfortunately, ASP.NET 1.1 has no built-in support for master pages, so you have to build a solution yourself The simplest way is to define a site layout and simply enforce it—tell your developers “this is what it must look... the default set for ASP.NET by declaring it in the section of machine.config or web.config: 351 352 8 Building Adaptive Controls Then your ASP.NET pages can use... Viewing details of an assembly in the GAC with the NET Configuration tool Testing the GAC-Installed Control After you have installed the assembly for the SpinBox control in the GAC, you can use it in an ASP.NET page The demonstration page provided for this is identical to the one for the adaptive version of the control, with the exception of the Register directive To register an assembly that is in the... the usual way The batch file make.bat (also in the samples you can download from www.daveandal.net/books/6744/) does this for you, by executing the following command: C:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc /t:library ➥/out:GACSpinBox.dll /r:System.dll,System.Web.dll gac-spinbox.vb 349 350 8 Building Adaptive Controls Installing the SpinBox Assembly into the GAC After you compile the class file,... following: n Hide the implementation from the user in a far more comprehensive manner than with user controls n Easily raise events that can be handled in the hosting page just like the events of the standard ASP.NET controls n Install the controls in the GAC so that they are available to any application running on the machine This chapter looks at the basic issues involved in building server controls, including... install the assembly into the GAC The batch file named addtogac.bat (in the samples you can download from www.daveandal.net/books/6744/) contains the command required: “C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\gacutil” /i GACSpinBox.dll If all goes well, you’ll see the message “Assembly successfully added to the cache.” Listing and Removing the Assembly from the GAC The samples for this book, which you... you can download from www.daveandal.net/books/6744/) in a command window when the current folder contains the source class file The following command is required: “C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\sn” -k GACSpinBox.snk Notice that you provide the full path to the sn.exe utility to make sure that you use the correct version if you have more than one version of the NET Framework installed . ease of devel- opment that ASP. NET brings. What you want is the master pages scenario that ASP. NET 2.0 provides, but for ASP. NET 1. 1. Master pages give you. defaultLanguage=”vb”> </system.web> FIGURE 8. 21 Viewing details of an assem- bly in the GAC with the .NET Configuration tool. 11 0672326744 CH08 5/4/04 12 :24 PM Page 3 51 Please purchase PDF Split-Merge

Ngày đăng: 21/01/2014, 09:20

Mục lục

  • cover.pdf

  • page_r1.pdf

  • page_r2.pdf

  • page_r3.pdf

  • page_r4.pdf

  • page_r5.pdf

  • page_r6.pdf

  • page_r7.pdf

  • page_r8.pdf

  • page_r9.pdf

  • page_r10.pdf

  • page_r11.pdf

  • page_r12.pdf

  • page_1.pdf

  • page_2.pdf

  • page_3.pdf

  • page_4.pdf

  • page_5.pdf

  • page_6.pdf

  • page_7.pdf

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan