Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
859,9 KB
Nội dung
LISTING 6.26 The Page_Load Event Handler Code for Counting Postbacks
Sub Page_Load()
‘ add client-side event attributes to button and form here
If Page.IsPostBack Then
‘ collect session and viewstate counter values
Dim sPageLoads As String = Session(“PageLoads”)
Dim sPageIndex As String = ViewState(“PageIndex”)
If sPageLoads = “” Then
lblMsg.Text &= “<b>WARNING:</b> Session support “ _
& “is not available.”
Else
Dim iPageLoads As Integer = Integer.Parse(sPageLoads)
Dim iPageIndex As Integer = Integer.Parse(sPageIndex)
‘ see if this is the first time the page was submitted
If iPageLoads = iPageIndex Then
lblMsg.Text &= “Thank you. Your input [“ _
& iPageLoads.ToString() & “] has been accepted.”
‘ *************************************
‘ perform required page processing here
‘ *************************************
‘ delay execution of page before sending response
‘ page is buffered by default so no content is sent
‘ to the client until page is complete
Dim dNext As DateTime = DateTime.Now
dNext = dNext.AddSeconds(7)
While DateTime.Compare(dNext, DateTime.Now) > 0
‘ wait for specified number of seconds
‘ to simulate long/complex page execution
End While
Else
lblMsg.Text &= “<b>WARNING:</b> You clicked the button “ _
& (iPageLoads - iPageIndex + 1).ToString() & “ times.”
End If
‘ increment counters for next page submission
Session(“PageLoads”) = (iPageLoads + 1).ToString()
6
Client-Side Script Integration
238
09 0672326744 CH06 5/4/04 12:24 PM Page 238
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
239
Useful Client-Side Scripting Techniques
ViewState(“PageIndex”) = (iPageLoads + 1).ToString()
End If
Else
‘ preset counters when page first loads
Session(“PageLoads”) = “1”
ViewState(“PageIndex”) = “1”
lblMsg.Text=”Click the button to submit your information”
End If
End Sub
If you look at the code at the end of Listing
6.26, you can see that when it’s not a post-
back, you just set the viewstate and session
values to
“1”
(remember that they are stored
as
String
values). The viewstate of the page is
a useful bag for storing small values. These
values are encoded into the rest of the view-
state that ASP.NET automatically generates for
the page it is creating.
If this is a postback, the first step is to check
whether sessions are supported by looking for
the value you stored against the
PageLoads
key
when the page was initially created. The
process will not work if there is no value in
the session, and at this point, you need to
decide what you want to do about it. If you
absolutely need to perform the postback
counting process, you can warn the user that
he or she must enable sessions, or perhaps
you would redirect the user to a page that
uses ASP.NET cookieless sessions. You might
even decide to use cookieless sessions for all
clients.
Comparing the Postback Counter Values
The next step in the process of checking for
multiple postbacks is to compare the values
in the viewstate and the session. If they are the same, you can accept the postback and start
processing any submitted values. The sample page displays a message to indicate the current
postback counter value. The code in the page uses a loop that waits seven seconds to simulate a
LISTING 6.26 Continued
Using a Hidden Control to Store Values
An alternative approach would be to store the
value in a
hidden-type input control on the
page. However, this is less secure than using
the viewstate because the value can be viewed
by users, who might be tempted to try to spoof
the server by changing the value (although this
is probably an unlikely scenario).
Using Cookieless Sessions in ASP.NET
The ASP.NET cookieless sessions feature
provides session support for clients that do
not themselves support HTTP cookies. It
works by “munging” (that is, inserting) the
session ID into the URL of the page and auto-
matically updating all the hyperlinks in the
page to reflect the updated URL. All you need
to do to enable cookieless sessions is place
in the root folder of the application a
web.config file that contains the following:
<configuration>
<system.web>
<sessionState cookieless=”true” />
</system.web>
</configuration>
09 0672326744 CH06 5/4/04 12:24 PM Page 239
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
long process. Afterward, you can increment
the counter values in the viewstate and
session, and then you can allow the page to
be created and sent to the client.
However, if the viewstate and session values
are different, you know that the postback has
occurred from a page that you are already
processing. Rather than try to cancel the
existing processes that were started by previous postbacks from this instance of the page, you
just ignore the current postback and don’t carry out the processing again. Instead, you return a
message to the user, indicating how many times he or she clicked the button. You can see the
result in Figure 6.11.
6
Client-Side Script Integration
240
FIGURE 6.11 The result in the one-click
button example when the
form is submitted more than
once.
Summary
This chapter takes a more comprehensive look at how the client-side script used in the
ComboBox
control, described at the end of Chapter 5, works. It also discusses the three main requirements
for producing interactive pages when using client-side script:
n
Access to all the elements on the page, with the ability to read and set the content of each
one, show or hide it, and generally manipulate it
n
Access to a full range of keypress events, so that you can manage how a control behaves,
depending on user interaction via the keyboard
n
The ability to statically and dynamically position elements outside the flow model, using
fixed (absolute) coordinates that are relative to a container
Following this discussion, the chapter delves deeper into integrating client-side code with
ASP.NET server-side code to produce useful controls and interactive pages. This chapter consid-
ers four topics:
n
Trapping an event that occurs on the client and popping up a confirmation dialog before
carrying out the action on the server, by displaying a
confirmation
dialog before deleting a
row in a
DataGrid
control.
Trigger-Happy Button Clicks
Note that it’s possible to click the button so
quickly that ASP.NET does not have time to
start processing the page and update the
session value. In this case, the page reports
fewer clicks than actually occurred when the
final submit action has been processed.
09 0672326744 CH06 5/4/04 12:24 PM Page 240
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
241
Summary
n
Trapping the Return key to prevent a form from being submitted, or in fact trapping any
keypress that might not be suitable for a control or an application you are building.
n
Handling individual keypress events, by implementing a
MaskedEdit
control.
n
Creating a button that can be clicked only once, to prevent the user from causing a second
postback when nothing seems to be happening at the client.
So, as you’ve seen, getting exactly the performance, appearance, or usability you want is not
always easy (or even possible!). However, you can create components and build reusable content
that far exceeds the standard output that ASP.NET can provide on its own. Chapter 7 continues
this theme by looking at some more user controls that combine with the features of ASP.NET to
make building interactive pages easier.
09 0672326744 CH06 5/4/04 12:24 PM Page 241
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
09 0672326744 CH06 5/4/04 12:24 PM Page 242
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
7
Design Issues
for User
Controls
Chapters 5, “Creating Reusable Content,”
and 6, “Client-Side Script Integration,” look
at some techniques for building reusable
content for Web pages and Web applica-
tions and the advantages these techniques
can provide. This chapter continues the
theme by looking in detail at some more
user controls. You’ll see more useful ways
that you can create different types of
controls and provide functionality that is
not available using the standard set of
ASP.NET server controls and the HTML
elements supported by the browser.
In Chapter 5, you built a combo box as a
user control and learned about the basic
issues involved. Then, in Chapter 6 you
built a page that implements a
MaskedEdit
control.
In this chapter you’ll see how you can
convert that control into a user control.
You’ll also learn about another useful
control—the
SpinBox
control.
User controls do not have to provide a user
interface. In this chapter you’ll also see a
couple user controls that provide extra func-
tionality for Web applications, but without
actually creating elements in the browser.
IN THIS CHAPTER
The Effect of User Controls on Design
and Implementation 244
Building a
SpinBox User Control 254
Integrating Client-Side Script Dialogs 267
Browser-Adaptive Script Dialogs 274
Integrating Internet Explorer Dialog
Windows 283
Browser-Adaptive Dialog Windows 290
Summary 294
10 0672326744 CH07 5/4/04 12:26 PM Page 243
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Instead, they expose methods that make it easier to integrate dialogs and other client-side
features with your ASP.NET code.
The final topic in this chapter is something that, to some extent, previous chapters glossed over:
how to cope with different browser types. This chapter discusses some of the major issues and
shows how to build controls that adapt to suit different browsers.
The Effect of User Controls on Design and
Implementation
Converting sections of an ASP.NET page into a reusable user control is usually a reasonably
simple task. HTML and text (content) work just the same way, as does any client-side script. And
server controls declared in a user control produce the same visible output and work the same
way, whether they’re placed directly into an ASP.NET page or encapsulated in a user control.
The things that do change and that you need to bear in mind, are listed next. They may not all
apply to the controls you build, but you’ll see all these issues in this chapter:
n
The position of the server controls within the hierarchy of the final ASP.NET page changes
when the server controls are placed into a user control. The user control becomes a
container, and its constituent server controls are located within the
Controls
collection of
the user control. This changes the ID of the contained controls.
n
User controls should support being used more than once within the same page, so they
must avoid containing HTML or controls that can only appear once in the final ASP.NET
page (for example, the
<html>
,
<head>
, and
<body>
elements, and the server-side
<form
runat=”server”>
element).
n
If you need client-side script to be injected into a page, you must be sure that only one
instance of the script is created, regardless of how many user controls reside on the final
ASP.NET page (unless each code section is specific to that instance of the user control).
n
If your user control requires any images or other resources to be loaded from disk, you
must decide how these will be referenced. For example, if an
Image
control within a user
control uses
ImageUrl=”myfile.gif”
, ASP.NET will expect the image to reside in the same
folder as the user control. It will modify the path automatically, depending on the loca-
tion of the page that hosts the user control.
n
You need to consider whether to expose settings for the elements and behavior of a user
control as properties rather than expecting people who use the user control to reference
individual items within it. Exposing useful values as properties can make working with a
user control a great deal simpler, and it allows you to validate values and perform other
actions when property values are read or set.
n
User controls can also expose methods, which can be functions that return values or just
routines (for example,
Sub
in Visual Basic .NET,
void function
in C#) that do something
within the control. You need to think about whether to allow the user to pass in the
7
Design Issues for User Controls
244
10 0672326744 CH07 5/4/04 12:26 PM Page 244
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
245
The Effect of User Controls on Design and Implementation
values required for these methods as parameters or expect them to set any required values
by using
Public
properties of your user control.
n
If controls contained within your user control will have client-side event handlers
attached, you must pass in all the values you need as parameters and not embed generated
values within the client-side script unless they are the same for every instance of the user
control. You’ll see what we mean by this in more detail in the following section.
n
If the contained controls raise events that you want to handle, you must handle these
events within the user control. You cannot write event handlers in the hosting page for
events exposed by server controls you declare within a user control.
Converting the MaskedEdit Control Page to a User Control
The
MaskedEdit
control example in Chapter 6 was written as an ASP.NET page (
maskedit.aspx
),
although it uses a second ASP.NET page (
mask-image.aspx
) to generate the background image for
the text box (see Figure 7.1).
FIGURE 7.1 The MaskedEdit user control
sample page.
To create a user control that implements the
MaskedEdit
control, you just need to lift out the
relevant code and declarations and place them into an
.ascx
file. Because the file implements a
user control, it must start with a
Control
directive. You can turn on debugging during develop-
ment to make it easier to see what’s happening if an error occurs:
<%@Control Language=”VB” Debug=”True” %>
Then you can declare the user interface section. In this case, it’s just an ordinary ASP.NET Web
Forms
TextBox
control. You specify the default value for the columns and provide an ID so that
you can refer to it in code within the user control:
<asp:TextBox id=”txtMaskEdit” Columns=”25” runat=”server” />
Defining the User Control Interface
As you go through the process of converting content from an ASP.NET page into a user control,
you must decide what properties and methods you want to expose from that user control. For
10 0672326744 CH07 5/4/04 12:26 PM Page 245
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
this example, only two properties are exposed: a
String
value that defines the mask for the text
box and the size of the font to use within the text box as an
Integer
value. Because you won’t
validate the values that are applied to the properties in this example, you can use the simplest
approach and just declare them as
Public
variables, as shown here:
Public Mask As String
Public FontSize As Integer
The values effectively become fields of the user control that can be accessed from the hosting
ASP.NET page.
You also need to declare one internal variable, which you will use to store the font name for the
text box and the image you generate to represent the mask. You know that it must be a mono-
spaced (fixed-pitch) font, so this example is limited to the Courier New font that is installed
with Windows:
Private _font As String = “Courier New”
Notice that this (intentionally) small set of
Public
properties severely limits opportunities for
users of the user control to affect how the control behaves. Users create an instance of the
control (either declaratively or in code), but they cannot easily access the controls within it. For
example, if you declare an instance of the
MaskedEdit
control like this:
<ahh:MaskEdit id=”oCtrl” runat=”server” />
you might be tempted to try to access the text box named
txtMaskEdit
within it (perhaps to
change the number of columns), by using this:
oCtrl.txtMaskEdit.Columns = 100 ‘ produces a compiler error
This fails because the text box declared
within the user control is generated as a
Protected
member of the control. The preced-
ing code will result in the error “txtMaskEdit
is not accessible in this context because it is
‘Protected’.” However, users can get around
this by using the built-in
FindControl
method
of the user control. This searches the
Controls
collection and returns the control with the
matching ID value as a reference to the
Control
type. If you convert this into a
TextBox
type, the text box can be accessed:
CType(oCtrl.FindControl(“txtMaskEdit”), TextBox).Columns = 100
This introduces an interesting point. If you or developers who use your control in their pages
can access the controls it contains, do you need to expose properties that provide access to the
controls? Maybe it’s just as easy to allow developers to set the number of columns on a text box
by using the technique just demonstrated.
7
Design Issues for User Controls
246
User Controls Cannot Hide Their Content
Bear in mind that you can’t encapsulate (and
hide) controls and content in a user control
as you can with a custom server control—like
those you’ll be meeting in Chapter 8,
“Building Adaptive Controls.” However, user
controls are only plain-text files anyway, so
developers who make use of a user control
can always open it to see what’s inside (and
modify it as well, if they wish!).
10 0672326744 CH07 5/4/04 12:26 PM Page 246
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
247
The Effect of User Controls on Design and Implementation
In fact, that is probably not a good idea. It means that developers have to dig about inside the
user control in a text editor to find the value of ID for the control they want to access and risk
runtime errors through using the
FindControl
method (which cannot perform type checking at
compile time). And if they are using the control in a development environment that provides
IntelliSense or lists of properties and methods, only the
Public
interface members exposed by
the control will be visible.
If you want to expose the constituent controls from a user control, you should do so as proper-
ties of the user control. For example, Listing 7.1 shows how you could expose the text box
(which has the
id
attribute value
txtMaskEdit
) as a read-only property from the
MaskedEdit
user
control.
LISTING 7.1 Exposing a Constituent Control from a User Control
Public ReadOnly Property Textbox As Textbox
Get
Return txtMaskEdit
End Get
End Property
Users of the control can then access the text box and its properties in the usual way:
oCtrl.Textbox.Columns = 100
The issue now is that the users can set any properties they want on the control. In this case,
specifying the number of columns, the font name, or the background image will effectively
break the control. The only redeeming feature is that users are likely to make changes in the
Page_Load
event of the hosting page, which runs before the
Page_Load
event of the user control.
Therefore, you can make sure that any specific properties that might break the control if set to
inappropriate values are set back to suitable values in the
Page_Load
event of the user control.
The Page_Load Event Handler
Not surprisingly, most of the code used in the
MaskedEdit
page to create and set the attributes
and properties of the controls just needs to be lifted out of the page and placed into the
Page_Load
event handler of the user control. This includes the code shown in Listing 7.2, which
sets the
style
attributes for the text box, generates the correct format for the background mask
image, and creates the ToolTip.
LISTING 7.2 The Page_Load Event Handler for the MaskedEdit User Control
Sub Page_Load()
‘ add style attributes to Textbox
txtMaskEdit.Style(“font-family”) = _font
txtMaskEdit.Style(“font-size”) = FontSize & “pt”
‘ create mask for display as Textbox background
10 0672326744 CH07 5/4/04 12:26 PM Page 247
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... this code within every control, the ASP.NET installation routine places it into a separate file named WebUIValidation.js, within the special folder named aspnet_client in the root of all your Web sites The aspnet_client folder contains a subfolder named system.web, and within that is a subfolder for each version of ASP.NET installed on the machine So, in version 1.1, the validation controls inject... the program aspnet_ regiis.exe, which runs as part of the installation program for ASP.NET However, the program only creates the aspnet_client folder within any existing Web sites If you add a new site to IIS on your server, you must manually copy this folder to it The folder also contains scripts for other features of ASP.NET, such as the SmartNav.js script for implementing smart navigation 249 250... Controls Using Script Files Across Multiple Applications Recall that the scope rules of ASP.NET limit a user control to the same virtual application as the pages that host it In other words, you can reference an ascx user control from an aspx page only if the user control is in a folder located within the same ASP.NET application You can’t share a single user control across multiple applications However,... However, the issue is not quite as obvious where the text box is concerned If you set the builtin AutoPostback property to True for a standard ASP.NET TextBox control, the page will be posted back to the server automatically when the text box loses the input focus (ASP.NET does this by injecting client-side script into the page to handle the blur event.) However, you want to use the blur event to validate... not in the list, you just ignored it However, this is not the way most of the ASP.NET controls work If you specify a SelectedValue property value that is not in the list for a ListBox control, for example, an ArgumentOutOfRangeException error is thrown In the SpinBox control, you follow the same approach as the standard ASP.NET server controls If the user specifies an invalid value for any of the four... technique as the ComboBox control you built in Chapter 5 to position the elements it requires A element with the style selector position:relative forms the container, and within this you place an ASP.NET TextBox control and two ImageButton controls The ImageButton controls use position:absolute and have the top selector set so that they will be correctly positioned vertically in relationship to... separate configuration settings However, it often makes sense to pool and reuse resources, as well as to separate them to make maintenance, debugging, and upgrades easier For example, take a look at the ASP.NET validation controls When the browser is Internet Explorer 5 or above, these server controls inject considerable amounts of JavaScript code into the page to handle client-side validation and display... specify the behavior and appearance of the SpinBox control The Columns property specifies the width of the text box within the control, in the same way that it is used to specify the width of a normal ASP.NET TextBox control The value is of type Integer, approximately representing the number of characters that will be visible in the text box The three properties that specify the behavior of the control... discuss the particularly interesting points of the code in more depth in the following sections The specific points of interest are: n Implementing AutoPostback so that the control behaves like a standard ASP.NET Web Forms control n Ensuring that the value within the control is always valid when a page is submitted n Ensuring that values provided for properties of the control are valid and deciding what... about setting the size of the control The ComboBox control from Chapter 5 exposes a property named Width, which is used to set the size of the control, in pixels However, to match the properties of the ASP.NET TextBox control, you expose a property named Columns for the SpinBox control But how do you relate the width of the text box with the setting of the Columns property? The browser uses the current . example in Chapter 6 was written as an ASP. NET page (
maskedit.aspx
),
although it uses a second ASP. NET page (
mask-image.aspx
) to generate the background. version 1. 1, the validation controls inject a
<script>
element into the page that specifies
this file (in the folder
/aspnet_client/system_web /1_ 1_4322/
)