第四章 高级控件编程
主要内容:
l 使用视图状态(启用和禁用特定控件的视图状态、禁用整个页面的视图状态。如何将自己的变量存储在视图状态中)
l 显示和隐藏内容
l 使用复杂控件(Calendar、AdRotator、HTMLInputFile)
1. 使用视图状态
默认情况下,表单发送之间几乎所有ASP.NET控件都会保留它们的属性值。
视图状态,不依赖于任何特殊的服务器或浏览器属性。具体的说,它不依赖于cookie、会话变量、应用程序变量。
视图状态是用一个名为【_VIEWSTATE】的(隐藏表单域)实现的,这个表单域在每个Web表单页面中自动创建。
使用得当会对网站的性能产生积极效果。(例如:用一个支持视图状态的控件显示数据库数据,就不必在每次都获取数据。【表单的各次发送之间,可以自动在视图状态中保留数据】)
1.1 禁用视图状态
案例一:
如果将大量数据装载进隐藏的_VIEWSTATE表单域,而你并不想这么做,因为担心表单数据会显著减慢页面的显示速度。
案例二:
如果想在每次装载页面时,自动对控件进行重新初始化,那么也可能希望禁用视图状态。
注意:即使禁用了视图状态,表单控件(比如TextBox或RadioButtonList)也会在各次发送之间保留它们的值。这些值不需要保留在_VIEWSTATE中,因为每次表单发送时,它们都被实际发送回服务器。 |
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) If Not IsPostBack Then lblMessage.Text = "随便说点什么把" lblMessage2.Text = "第二代但是看看啦上课了" End If End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>ViewState</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="lblMessage" Text="label1" runat="server" /> <br /> <asp:Label ID="lblMessage2" EnableViewState="false" Text="label2" runat="server" /> <p /> <asp:Button ID="button1" Text="Just Submit" runat="server" OnClick="btn1_Click" /> </div> </form> </body> </html> |
在第一次装载页面时,设置Label控件的语句生效了,由于第二个Label控件没有保留视图状态(EnableViewState设为false),所以单击Button控件后,第二个Lable内容没有保留。这是禁用个别控件视图状态的方法。
如果要【禁用整个页面的视图状态】,应该【修改Page指令的EnableViewState属性】。
<%@ Page Language="VB" EnableViewState="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) If Not IsPostBack Then lblMessage.Text = "页面第一次装载时,设置内容" End If End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="lblMessage" runat="server" /> <p /> <asp:Button ID="Button1" Text="马上提交" runat="server" /> </div> </form> </body> </html> |
1.2 将值添加到视图状态
通过将【值添加到状态袋类state bag class】,可以在代码中利用视图状态。
如果【将值添加到这个类中】,它们就被自动地添加到隐藏的VIEWSTATE表单变量中;因此,可以(跨多次表单发送使用它们)。
使用下面的语句将值添加到状态袋中: ViewState(“项名称”)=”项值” |
警告: ViewState是大小写敏感的。 |
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) ViewState("TotalCount") += 1 If ViewState("TotalCount") = 10 Then ViewState("TotalCount") = 1 End If lblCount.Text = ViewState("TotalCount") End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>State Bag</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" Text="点我吧" runat="server" OnClick="Button1_Click" /> <p /> <asp:Label ID="Label1" Text="按钮点击次数:" runat="server" /><asp:Label id="lblCount" Runat="server" /> </div> </form> </body> </html> |
2 显示和隐藏内容
假设:
打算创建一个具有可选部分的表单。比如,一个在线税务表单,其中的一部分包含只针对已婚纳税人的问题,开发者当然希望根据实际情况显示或者隐藏它。
又或者,希望在税务表单上添加一个帮助按钮,可能需要根据用户的意愿显示或隐藏那些帮助用户填写表单的详细说明。
最后,你可能希望将税务表单分割成几个页面,浏览者每次只能看到税务表单的一部分内容。
以上种种,你可以通过【设置显示和隐藏表单上的控件的属性】的方法来达到目的。
可以通过,控制个别控件和控件组的Visible和Enable属性显示和隐藏页面内容。
2.1 使用Visible和Enable属性
每个控件(包括HTML和Web控件)都有一个Visible属性,它决定是否显示此控件。当控件的Visible属性值为False时,控件在页面上不显示,并且也不进行预显示和显示所需的处理。
Web控件(以及不是所有的HTML控件)有一个Enable属性。如果Enable属性值为False,而且使用的IE在4.0以上版本,那么控件显示为灰色,并且不起作用。使用其他浏览器时,控件【可能】不显示为灰色,但是它不会起作用。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub lbtnVisible_Click(ByVal sender As Object, ByVal e As System.EventArgs) If txt1.Visible = True Then txt1.Visible = False lb1.Visible = False hl1.Visible = False btn1.Visible = False lbtnVisible.Text = "显示" Else txt1.Visible = True lb1.Visible = True hl1.Visible = True btn1.Visible = True lbtnVisible.Text = "隐藏" End If End Sub
Protected Sub lbtnEnable_Click(ByVal sender As Object, ByVal e As System.EventArgs) If txt1.Enabled = True Then txt1.Enabled = False hl1.Enabled = False lb1.Enabled = False btn1.Enabled = False lbtnEnable.Text = "允许" Else txt1.Enabled = True hl1.Enabled = True lb1.Enabled = True btn1.Enabled = True lbtnEnable.Text = "禁止" End If End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> 文本框:<asp:textbox id="txt1" text="some text 一些文字" runat="server" /> <p /> 超链接:<asp:hyperlink id="hl1" text="感谢页面" navigateurl="StateBag.aspx" runat="server" /> <p /> 链接按钮:<asp:linkbutton id="lb1" text="链接按钮" runat="server" /> <p /> 普通按钮:<asp:button id="btn1" text="提交" runat="server" /> <hr /> <asp:LinkButton ID="lbtnVisible" Text="隐藏" runat="server" OnClick="lbtnVisible_Click" /> <br /> <asp:LinkButton ID="lbtnEnable" Text="允许?" runat="server" OnClick="lbtnEnable_Click" /> </div> </form> </body> </html> |
注意:在使用不同的浏览器时,点击“允许/禁止”按钮的效果是不同的。
在IE中,不能在已经被禁用的表单控件中输入任何文本,Button按钮显示为灰色,而且不能点击它。
注意:Enable属性对表单控件的【外观】的实际影响取决于浏览器如何解释HTML Disable属性(解释方法),Disable属性是HTML4.0标准的一部分(它应该应用于所有标准的HTML表单控件) |
下面一点我很疑惑:“不管什么浏览器,Disable属性不会影响HyperLink控件的功能”(而在实际中,我的示例确实影响了它)
Disable属性总是会修改【链接按钮LinkButton】的外观。
2.2 使用Panel控件
使用Panel控件,可以成组的隐藏控件(它包含的控件)。
l Panel的属性
属性 |
说明 |
BackImageURL |
获取或设置在面板内容后面显示的背景图像的URL |
HorizontalAlign |
设置面板内容的水平对齐方式。 有效值:Center、Justify、Left、NotSet和Right |
Wrap |
设置为True时,面板内容回绕显示。默认值True |
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub submit_Click(ByVal sender As Object, ByVal e As System.EventArgs) '如果选中的是其他站点一项,显示第二面板 If rbl1.SelectedIndex = 3 Then panel2.Visible = True Else panel2.Visible = False End If End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Panel ID="panel1" runat="server" > 选择一个你收藏的站点:<br /> <asp:RadioButtonList ID="rbl1" runat="server"> <asp:ListItem Text="百度"/> <asp:ListItem Text="电驴" /> <asp:ListItem Text="博客园" /> <asp:ListItem Text="其它站点" /> </asp:RadioButtonList> </asp:Panel> <asp:Panel ID="panel2" Visible="false" runat="server"> <p /> 其他站点: <br /> <asp:TextBox ID="txtOtherSite" runat="server" /> </asp:Panel> <p /> <asp:button ID="submit" text="Submit!" runat ="server" OnClick="submit_Click" /> </div> </form> </body> </html> |
Panel控件是作为其他控件的容器。Panel控件的Visible属性设为False时,会隐藏面板,同时隐藏其中包含的所有控件。
2.3 模拟多页面表单
假设你设计的表单上有50个问题,你希望将它们分进多个页面中。实现此设想的方法之一就是,为每组问题创建一个单独的ASP.NET页面。
但是,创建跨多个页面的表单要进行许多工作。比如,当用户在页面5上之时,你需要一些方法存储用户在页面1中输入的答案,当然,这可以使用隐藏的表单域或者Session变量来实现,但是还有一个更容易的办法,那就是将所有问题放在单个ASP.NET页面中,转而使用Panel控件来显示或隐藏表单中的不同部分。
这个方法的优点是,表单中输入的所有答案都被自动地保留了。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) '装载页面时,在隐藏状态域中设置当前页变量 If Not IsPostBack Then ViewState("CurrentPage") = 1 End If End Sub
Sub btnNextPage_Click(ByVal s As Object, ByVal e As EventArgs) Dim pnlPanel As Panel Dim strPanelName As String '隐藏上一个面板 strPanelName = "pnlForm" & ViewState("CurrentPage") pnlPanel = FindControl(strPanelName) 'Page.FindControl,在页命名容器中搜索指定的服务器控件 pnlPanel.Visible = False '显示当前页 ViewState("CurrentPage") += 1 '将隐藏视图状态中记录当前页的变量加1 strPanelName = "pnlForm" & ViewState("CurrentPage") pnlPanel = Page.FindControl(strPanelName) pnlPanel.Visible = True End Sub
Sub btnPrevPage_Click(ByVal s As Object, ByVal e As EventArgs) Dim pnl As Panel Dim strPnlName As String '先隐藏 strPnlName = "pnlForm" & ViewState("CurrentPage") pnl = Page.FindControl(strPnlName) pnl.Visible = False '再显示 ViewState("CurrentPage") -= 1 strPnlName = "pnlForm" & ViewState("CurrentPage") pnl = Page.FindControl(strPnlName) pnl.Visible = True End Sub
Sub btnFinish_Click(ByVal s As Object, ByVal e As EventArgs) pnlForm4.Visible = True pnlForm3.Visible = False
lblSummary.Text = "<h2>You Entered:</h2>" lblSummary.Text &= "<li>First Name:" & txtFirstname.Text lblSummary.Text &= "<li>Last Name:" & txtLastname.Text lblSummary.Text &= "<li>Color:" & txtFavColor.Text lblSummary.Text &= "<li>Philosopher:" & radlFavPhilosopher.SelectedItem.Text End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Panel ID="pnlForm1" runat="server"> <h3>Page <%=ViewState("CurrentPage") %> of 3</h3> <hr /> FirstName:<asp:TextBox ID="txtFirstname" runat="server" /> <p /> LastName:<asp:TextBox ID="txtLastname" runat="server" /> <hr /> <asp:Button Text="Next Page >>" OnClick="btnNextPage_Click" runat="server" /> </asp:Panel>
<asp:Panel ID="pnlForm2" runat="server" Visible="false"> <h3>Page <%=ViewState("CurrentPage") %> of 3</h3> <hr /> Favorite color: <asp:TextBox ID="txtFavColor" runat="server" /> <hr /> <asp:Button Text="<< 上一页" onclick="btnprevpage_click" runat="server" /> <asp:Button Text="下一页 >>" onclick="btnnextpage_click" runat="server" /> </asp:Panel> <asp:Panel ID="pnlForm3" runat="server" Visible="false"> <h3>Page <%=ViewState("CurrentPage") %> of 3</h3> <hr /> Favorite Philosopher: <asp:RadioButtonList ID="radlFavPhilosopher" runat="server"> <asp:ListItem Text="Frege" Selected="True" /> <asp:ListItem Text="Russell" /> <asp:ListItem Text="Carnap" /> </asp:RadioButtonList> <hr /> <asp:Button Text="<< Prev Page" OnClick="btnprevpage_click" runat="Server" />
<asp:Button text="Finish" OnClick="btnfinish_click" runat ="server" /> </asp:Panel>
<asp:panel ID="pnlForm4" runat="server" Visible="false"> <asp:Label ID="lblSummary" runat="server" /> </asp:panel> </div> </form> </body> </html> |
2.4 通过程序(代码)添加控件
ASP.NET页面是由控件搭建的。
页面的每一个元素(包括静态的文本和HTML内容)都有一个控件表示。
在Page类中,属性Controls包含了其页面中所有控件的列表。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Dim strControlList As String Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) strControlList = "<ul>" DisplayControls(Page) strControlList &= "</ul>" lblOutput.Text = strControlList End Sub Sub DisplayControls(ByVal s As Control) Dim ctlControl As Control For Each ctlControl In s.controls DisplayControlInfo(ctlControl) strControlList &= "<ul>" DisplayControls(ctlControl) strControlList &= "</ul>" Next End Sub Sub DisplayControlInfo(ByVal s As Control) strControlList &= "<li>Client ID:" & s.clientID strControlList &= "<li>Type:" & s.GetType.ToString strControlList &= "<li>ID:" & s.ID strControlList &= "<li>Naming Container:" & s.NamingContainer.ToString strControlList &= "<li>Page:" & s.Page.ToString strControlList &= "<li>Parent:" & s.Parent.ToString strControlList &= "<li>Unique ID:" & s.UniqueID strControlList &= "<p>" End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Panel ID="pnlPanel" runat="server"> <asp:Label ID="lblNewLabel" runat="server" /> </asp:Panel> UserName:<br /> <asp:TextBox ID ="txtUsername" runat="server" /> <p /> <asp:Button ID="btnButton" Text="提交姓名" runat="server" /> <hr /> <asp:Label ID="lblOutput" runat="server" />
</div> </form> </body> </html> |
控件属性介绍:
Control类的属性 |
说明 |
ClientID |
ASP.NET框架为每个控件自动产生的ID。它不是声明控件时分配给控件的ID |
ID |
声明控件时分配的ID |
NamingContainer |
包含当前控件的第一个实现了InamingContainer接口的父控件 |
UniqueID |
完全限定的惟一的控件ID。 如果一种控件被包含在不同名称的容器中,那么它们的id可能相同,但是它们的UniqueID绝对不同 |
2.5 将控件添加到页面
【通过将控件添加到页面的Controls集合中】,可以【将新控件添加到页面中】。
可以使用Add()方法将控件添加到Control集合的末尾。
也可以使用AddAt()方法将控件添加到Controls集合中特定的索引位置上。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) '在页面装载子例程中添加30个LiteralControl控件,打开页面会看到Hello!重复了30次 Dim intCounter As Integer For intCounter = 1 To 30 Controls.Add(New LiteralControl("Hello!<br/>")) Next End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div>
</div> </form> </body> </html> |
Controls属于集合类型,所以,你可以使用Remove()、RemoveAt()、Clear()等方法处理内部条目。
2.6 PlaceHolder控件
通常,我们不会将控件直接添加到页面的Controls集合中。
在大多数情况下,会希望将控件添加到页面上的特定位置。
你可以将控件添加到任何其他控件的Controls集合中。
但是,ASP.NET框架中包含了一个特殊的控件(PlaceHolder控件),它专门作为其他控件的容器。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) '演示如何使用PlaceHolder控件动态地将textBox控件添加到表单中 Dim intcounter As Integer Dim btnNewButton As Button For intcounter = 1 To 10 plhPlaceHolder.Controls.Add(New LiteralControl("<p/>Field " & intcounter & ": ")) plhPlaceHolder.Controls.Add(New TextBox) Next btnNewButton = New Button btnNewButton.Text = "click here!" plhPlaceHolder.Controls.Add(btnNewButton) End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>PlaceHolder控件演示</title> </head> <body> <form id="form1" runat="server"> <div> <asp:PlaceHolder ID="plhPlaceHolder" runat="server" />
</div> </form> </body> </html> |
2.7 动态产生表单
问题:假设你的表单需要包含数量不定的输入域。例如,你想创建一个简单的订单输入表单,可以在其中输入数量不定的产品订单。同一个表单允许输入单个表单,也允许输入25个表单。
可以动态的将表单域添加到表单中。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> '注意每次装载页面是,Page_Load子例程都会重新建立所有产品域。 '在动态地将新控件添加到表单时,在表单发送之间并不自动保留此控件。控件本身不被自动保留在页面的视图状态中。 '但是,在动态产生的表单域中输入的文本被自动保留在页面的视图状态中。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim intcounter As Integer If Not IsPostBack Then ViewState("productfieldcount") = 1 ElseIf ViewState("productfieldcount") > 1 Then For intcounter = 2 To ViewState("productfieldcount") AddProductField(intcounter) Next End If End Sub Sub AddProductField(ByVal strFieldNum As String) Dim litlabel As LiteralControl litlabel = New LiteralControl litlabel.Text = "<p><b>Product " & strFieldNum & ":</b>" plhProductFields.Controls.Add(litlabel) Dim txtTextBox As TextBox txtTextBox = New TextBox txtTextBox.ID = "txtProduct" & strFieldNum plhProductFields.Controls.Add(txtTextBox) End Sub Sub AddProductFieldCount(ByVal s As Object, ByVal e As EventArgs) ViewState("productfieldcount") += 1 AddProductField(ViewState("productfieldcount")) End Sub Sub btnSubmit_click(ByVal s As Object, ByVal e As EventArgs) Response.Redirect("diaplay.aspx") End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <b>Customer Name:</b> <asp:TextBox ID="txtCustomer" runat="server" /> <p /> </div> <div style="background-color:Yellow;padding:10px"> <b>Product 1:</b> <asp:TextBox ID="txtProduct1" runat="server" /> <asp:PlaceHolder id="plhProductFields" runat="server" /> </div> <p> <asp:Button Text="增加产品域" onclick="AddProductFieldCount" runat="server" /> <asp:Button ID="btnSubmit" Text="提交完成的订单" onclick="btnSubmit_click" runat="server" /> </p> </form> </body> </html> |
2.8 动态产生列表条目
对于各种列表控件(比如RadioButtonList、CheckBoxList、DropDownList和ListBox),可以使用ListItemCollection集合的属性和方法动态地在这些控件中添加和删除条目。
l ListItemCollection集合对象的属性
属性 |
说明 |
Count |
返回集合中列表条目的数量 |
Item |
返回指定索引处的列表条目 |
l ListItemCollection集合对象的方法
Add |
添加新条目 |
AddRange |
添加一个条目数组 |
Clear |
删除所有条目 |
Contains |
如果ListItem集合包含指定的条目,那么返回True |
CopyTo |
将所有条目复制到一个数组中 |
FindByText |
根据Text值返回一个条目 |
FindByValue |
根据Value值返回一个条目 |
GetEnumerator |
返回条目的枚举器 |
IndexOf |
返回条目的索引号 |
Insert |
在集合中特定的索引位置插入一个条目 |
Remove |
从集合中删除一个条目 |
RemoveAt |
从集合中删除特定索引位置上的条目 |
可以使用列表控件的属性和方法在表单的元素之间建立复杂的交互操作。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> '当你点击商品列表框中的一个条目时,这个条目自动地添加到购物篮中 '下面的两个按钮,可以删除已经添加到购物篮中的商品条目 Protected Sub lstProducts_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) lstCart.Items.Add(lstProducts.SelectedItem) 'lstProducts.SelectedIndex = -1 End Sub
Protected Sub btnRemove_Click(ByVal sender As Object, ByVal e As System.EventArgs) lstCart.Items.Remove(lstCart.SelectedItem) End Sub
Protected Sub btnRemoveAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) lstCart.Items.Clear() End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <h2>商品:</h2> <asp:ListBox ID="lstProducts" Width="200" AutoPostBack="true" runat="server" OnSelectedIndexChanged="lstProducts_SelectedIndexChanged" > <asp:ListItem Text="Hair Dryer" /> <asp:ListItem Text="Shaving Cream" /> <asp:ListItem Text="Electric Comb" /> <asp:ListItem Text="Nail Polish" /> <asp:ListItem Text="French Toast" /> </asp:ListBox> <p /> <h2>购物篮:</h2> <asp:ListBox ID="lstCart" Width="200" SelectionMode="Multiple" runat="server" /> <br /> <asp:Button ID="btnRemove" Text="移去商品" runat="server" OnClick="btnRemove_Click" /> <asp:Button ID="btnRemoveAll" Text="移去全部" runat="server" OnClick="btnRemoveAll_Click" />
</form> </body> </html> |
3 使用复杂控件
3.1 使用Calendar控件显示交互式的日历
使用Calendar控件,可以在页面上显示交互式的日历。
这个控件允许选择选定的日、周或月。
还可以在每天显示自定义的内容。
Calendar的属性
属性 |
说明 |
CellPadding |
单元格的内容与其边框之间的像素数 |
CellSpacing |
单元格之间的像素数 |
DayNameFormat |
设置日名称的格式。 有效值:FirstLetter、FirstTwoLetters、Full和Short(默认) |
FirstDayOfWeek |
在日历的第一列中显示是一周内的哪一天。 有效值Default(默认) Friday Monday Saturday Sunday Thursday Tuesday Wednesday。 默认值表示采用服务器的本地设置。 |
NextMonthText |
如果ShowNextPrevMonth为True,那么这个属性指定Next Month超链接使用的文本 |
NextPrevFormat |
指定Next和Previous超链接的格式。有效值 CustomText(默认) FullMonth ShortMonth |
PrevMonthText |
如果ShowNextPrevMonth为True,那么这个属性指定Previous Month超链接使用的文本 |
SelectedDate |
包含一个DateTime值,它指定高亮显示的日子。默认值为TodaysDate |
SelectedDates |
包含一个DateTime条目的集合,它代表日历中高亮显示的多个日子。 |
SelectionMode |
决定日、周或月是否可以被选择。有效值是 Day(默认)、DayWeek、DayWeekMont和None |
SelectMonthText |
包含当SelectionMode是DayWeekMonth时用于选择周的HTML文本 |
SelectWeekText |
包含当SelectionMode是DayWeek或DayWeekMonth时用于选择周的HTML文本 |
ShowDayHeader |
如果为True,那么显示周内的日名称 |
ShowGridLines |
若为True,那么在日历中日子的周围画线 |
ShowNextPrevMonth |
若为True,那么显示NextMonth和Previous Month链接 |
ShowTitle |
若为True,显示日历的标题 |
TitleFormat |
决定在标题栏中如何显示月名。有效值Month和MonthYear |
TodaysDate |
指定一个DateTime值,它设置日历的当前日期 |
VisibleDate |
指定一个DateTime值,它设置要显示的月 |
Calendar的事件
OnDayRender |
在显示日历上的每个日单元格之前被引发 |
OnSelectionChanged |
当选择新的日、月或周时被引发 |
OnVisibleMonthChanged |
由点击Next Month或Previous Month链接引发 |
Calendar控件的一般用途包括显示活动提示。
可以在显示日历时自定义日历中每个单元格的外观,甚至可以在每个日单元格中显示一个超链接以提供更多的信息。
Calendar控件的另一个常见用途是进行日程安排。
因为,可以在日历上选择特定的日、周或月,所以可以使用这个控件标出约会或其他活动的日期。
1 自定义Calendar控件的外观
有三种方式可以自定义Calendar控件的外观:
l 可以使用所有控件共有的格式化属性(比如BackColor、ForeColor、Border、Font、Height、Width)
l 可以使用Calendar控件的常规格式化属性(这些属性包括ShowGridLines、NextMonthText、PrevMonthText和TitleFormat
<asp:Calendar ID="myCal" PrevMonthText="<img src='."imgs"PrevPage1.jpg'>" NextMonthText="<img src='./imgs/NextPage1.jpg'>" runat="server" /> |
想要“修改日历中显示日的方式”,应该修改DayNameFormat属性。(比如:值为FirstLetter,表示只显示日名称的第一个字母;若值为FirstTwoLetters,则表示只显示日名称的前两个字母;当值为Full,则显示完整的日名称;最好值为Short,那么显示三个字母的日名称缩写。
l 可以将一个或多个自定义的样式对象应用到控件上。
下面列出Calendar支持的样式对象。
对象 |
说明 |
DayHeaderStyle |
日历顶部列出的日名称的样式 |
DayStyle |
应用于日历中的每一日的样式 |
NextPrevStyle |
应用与下一月和前一月链接的样式 |
OtherMonthDayStyle |
应用于出现在当前月中其他月的日样式 |
SelectedDayStyle |
应用于当前选择的日样式 |
SelectedStyle |
应用于选择周或月的链接的样式 |
TitleStyle |
应用于日历的标题栏的样式 |
TodayDayStyle |
应用于当前日期的样式 |
WeekendDayStyle |
应用于周末的样式 |
n 除了TitleStyle对象以外,所有样式对象都支持TableItemStyle样式类的属性。
n TitleStyle对象支持基本样式类的所有样式。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>CanlendarStyle</title> </head> <body> <form id="form1" runat="server"> <div> 这个例子,将大多数日显示为蓝色,周末显示为绿色,今天是黄色,选择的日期为橘色 <asp:Calendar ID="myCal1" DayStyle-BackColor="blue" WeekendDayStyle-BackColor="green" TodayDayStyle-BackColor="Yellow" SelectedDayStyle-BackColor="Orange" runat="server" /> </div> </form> </body> </html> |
2 用Calendar控件选择日、周和月
在【默认】情况下,Calendar控件允许在日历上选择某一日,
但是,可以修改Calendar的属性使它允许选择周或月,
甚至,可以设置Calendar,使它不允许选择任何东西。
要想选择周或月,应该修改SelectionMode属性。可以将这个属性设置为Day、DayWeek、DayWeekMonth、None。
在修改SelectionMode属性以允许选择周或月之后,可以修改SelectWeekText和SelectMonthText属性为选择周或月显示不同的链接。
甚至可以使用一些语法为这个属性分配图像:
<asp:Calendar ID=”MyCal” SelectionMode=”DayWeekMonth”
SelectWeekText=”<img src=’./SelectWeek.gif’>”
SelectMonthText=”<img src=’./SelectMonth.gif’>” />
要想判读日历上已经选择的日期,应该使用SelectionChanged事件。当引发此事件时,可以使用SelectedDate属性判读被选择的日期,或者使用SelectedDates属性判断被选择的多个日期。
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub calCalendar_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Dim dtmDate As DateTime lblDates.Text = "<h2>你选择的日期如下:</h2>" For Each dtmDate In calCalendar.SelectedDates lblDates.Text &= "<li>" & dtmDate.ToString("D") Next End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Calendar ID="calCalendar" SelectionMode="dayWeekMonth" SelectWeekText="±选择星期◆" selectmonthtext="选择月份" runat="server" OnSelectionChanged="calCalendar_SelectionChanged" /> <p /> <hr /> <asp:Label ID="lblDates" runat="server" /> </div> </form> </body> </html> |
注意:在Calendar控件中,其SelectedDates属性表示被选择的日期集合,其中的每个条目是一个DateTime值。
3 显示日历日
当Calendar控件【显示】某一日时,控件引发DayRender事件。
编写一个处理此事件的子例程,可以在每个日历日上显示自定义的内容。
DayRender事件处理子例程格式如下:
Sub Calendar_DayRender(s As Object, e As DayRenderEventArgs)
End Sub
第二位的参数类型DayRenderEventArgs的属性如下:
属性 |
说明 |
Cell |
包含被显示的日的表格单元格 |
Cell.ColumnSpan |
一个整数值,表示单元格应该跨几个表格列 |
Cell.HorizontalAlign |
单元格的水平对齐方式。有效值Center、Justify、Left、NotSet和Right |
Cell.RowSpan |
一个整数值,表示单元格应该跨几个表格行 |
Cell.Text |
单元格中显示的文本 |
Cell.VerticakAlign |
单元格的垂直对齐方式。有效值Bottom、Middle、NotSet和Top |
Cell.Wrap |
如果是True,那么单元格的内容进行单词回绕 |
Day |
代表被显示的日的CalendarDay对象 |
Day.Date |
代表被显示的日的DateTime值 |
Day.DayNumberText |
一个字符串,代表被显示的日的数字 |
Day.IsOtherMonth |
若为True,那么被显示的日不再当前月中 |
Day.IsSelectable |
若为True,那么此日可以被选择 |
Day.IsSelected |
若为True,那么此日被选择 |
Day.IsToday |
若为True,那么此日是当前日 |
Day.IsWeekend |
若为True,那么此日是星期六或星期日 |
<%--这个程序演示“如何使用DayRender事件在Calendar控件中如何显示一个占星图--%> <%@ Page Language="VB" %> <%@ import Namespace="System.Drawing" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Dim rannum As New Random(23) Protected Sub myCal_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Dim ctlCell As TableCell '表示一个单元格的控件 Dim strHoroscope As String = "" ctlCell = e.Cell 'DayRenderEventArgs.Cell获取表示呈现在 Calendar 控件中的单元格的 TableCell 对象。 " Select Case rannum.Next(4) Case 0 strHoroscope = "今天你将很幸运" ctlCell.BackColor = Color.FromName("Green") Case 1 strHoroscope = "大霉运啊!在家待着吧!" ctlCell.BackColor = Color.FromName("Red") Case 2 strHoroscope = "这一天会有意外发生" Case 3 strHoroscope = "小心巨变!"
End Select
ctlCell.Controls.Add(New LiteralControl("<p>")) ctlCell.Controls.Add(New LiteralControl(strHoroscope)) End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <h1>Horoscope:</h1> <form id="form1" runat="server"> <asp:Calendar ID="myCal" Width="100%" CellPadding="10" ShowGridLines ="true" SelectionMode="none" runat="server" OnDayRender="myCal_DayRender" /> </form> </body> </html> |
对于日历上显示的每一天(表格子),都要调用Calendar_RendarDay 子例程。
注意,如何使用日历单元格的Controls集合。【要将新的内容添加到一个日单元格中,就将新控件添加到日历单元格的Controls集合中】
注意:也可以使用TableCell控件的Text属性,将文本添加到日历单元格。(这对于纯文本和HTML内容没有问题,但是【不能使用Text属性添加ASP.NET控件】)
4 创建交互式的日程安排程序
要创建的Web应用程序允许用户向日历中的任何一天添加备忘录,并且在各次访问之间保存这些备忘录。
<%--程序说明:此页面包含Calendar、TextBox和Button控件。 如果希望向一天中添加一个备忘录,那么在日历上选择这一天,在文本框中 输入备忘录,然后点击Save Changes按钮。 日历上的每一天有两维数组arrCalender代表。数组的第一个索引代表月, 第二个所有代表日。 对于日历上显示的每一天,调用Calendar_RenderDay子例程,如果有备忘录 与这一天相关联,那么这个子例程用橘色的背景色显示这一天。 在点击Save Changes按钮时,arrCalendar数组的内容被保存到磁盘。 这是在btnSave_Click子例程中完成的。数组被保存到c:驱动器根目录下的 schedule.bin文件中。 如果保存修改,以后在回到此页面,那么备忘录会被保留。 在第一次装载页面时,从磁盘上保存的schedule.bin文件获取备忘录。 第一次装载备忘录之后,从缓存中获取它们以便提高性能。--%> <%@ Page Language="VB" %> <%@ import Namespace="System.IO" %> <%@ import Namespace="System.Runtime.Serialization" %> <%@ import Namespace="System.Runtime.Serialization.Formatters.Binary" %> <%@ import Namespace="System.Drawing" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Dim arrCalendar(13, 32) As String '在页面装载时,从缓存或者磁盘这种备忘录 Sub page_load() Dim strmFileStream As FileStream Dim fmtrBinaryFormatter As BinaryFormatter If Cache("arrCalendar") Is Nothing Then If File.Exists("C:"schedule.bin") Then strmFileStream = New FileStream("c:"schedule.bin", FileMode.Open) fmtrBinaryFormatter = New BinaryFormatter arrCalendar = CType(fmtrBinaryFormatter.Deserialize(strmFileStream), Array) strmFileStream.Close() Cache("arrCalendar") = arrCalendar End If Else arrCalendar = Cache("arrCalendar") End If End Sub
Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) '把备忘录保存到文件中 Dim dtmDate As DateTime Dim strmFileStream As FileStream Dim fmtrBinaryFormatter As BinaryFormatter dtmDate = calSchedule.SelectedDate arrCalendar(dtmDate.Month, dtmDate.Day) = txtNotes.Text strmFileStream = New FileStream("c:"schedule.bin", FileMode.Create) fmtrBinaryFormatter = New BinaryFormatter fmtrBinaryFormatter.Serialize(strmFileStream, arrCalendar) strmFileStream.Close() Cache("arrCalendar") = arrCalendar End Sub
Protected Sub calSchedule_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) '选择一个日期之时 Dim dtmDate As DateTime dtmDate = calSchedule.SelectedDate txtNotes.Text = arrCalendar(dtmDate.Month, dtmDate.Day) End Sub
Protected Sub calSchedule_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) '显示每一个日单元格之时 Dim dtmDate As DateTime Dim ctlCell As TableCell dtmDate = e.Day.Date ctlCell = e.Cell If arrCalendar(dtmDate.Month, dtmDate.Day) <> "" Then ctlCell.BackColor = Color.FromName("Orange") End If End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Calendar id="calSchedule" Width="100%" ShowGridLines="true" runat="server" OnSelectionChanged="calSchedule_SelectionChanged" OnDayRender="calSchedule_DayRender" /> <p /> <asp:TextBox ID="txtNotes" TextMode="MultiLine" Columns="50" Rows="10" runat="server" /> <p /> <asp:Button ID="btnSave" Text="Save Changes" runat="server" OnClick="btnSave_Click" /> </div> </form> </body> </html> |
3.2 使用AdRotator控件显示广告条
可以使用AdRotator控件在网页上随即地显示广告条。
大多数情况下,AdRotator控件都与一个广告文件一起使用,这个广告文件包含要显示的广告条的属性列表。
AdRotator控件的属性
属性 |
说明 |
AdvertisementFile |
一个XML文件的路径,这个文件包含要显示的广告条的列表 |
KeywordFilter |
设置这个属性时,只返回匹配过滤器的广告条 |
Target |
点击广告条时,页面被显示在这个窗口或框架中。有效值_top、_new、_child、_self、_parent、_blank |
AdRotator的事件
OnAdCreated 引发AdCreated事件
广告文件的一般格式(XML):
<Advertisements>
<Ad>
<ImageUrl>URL of image to display</ImageUrl>
<TargetUrl>URL of page to link to</TargetUrl>
<AlternateText>
Text to show as ToolTip
</AlternateText>
<Keyword>keyword used to filter</Keyword>
<Impressions>relative weighting of ad</Impressions>
</Ad>
</Advertisements>
属性介绍:
l ImageUrl——广告上显示的图像的URL。它可以是相对或绝对路径。
l NavigateUrl——点击广告时要到达的页面。
l AlternateText——在不支持图像的浏览器上显示的替代文本。此属性也经常用于显示工具提示文本。
l Keyword——一个可选关键字,可以【用来对广告条进行分离】。可以与KeywordFilter属性一起使用,以便显示文件中不同类别的广告。
l Impressions——某个广告相对于文件中其他广告的出现频率。这个数值越高,广告显示的次数越多。
注意:除了ImageUrl以外,以上属性都是可选的。
提示:可以向广告文件中添加你自己的自定义属性。
跟踪AdRotator的显示
如果【添加一个子例程】来处理AdCreated事件,就可以跟踪每个广告条被显示的次数。可以使用这个子例程将广告统计数据记录到数据库表、XML文件或文件系统中。
当引发AdCreated事件时,AdCreatedEventArgs类的一个实例,被传递给处理此事件的子例程。
AdCreatedEventArgs的属性
属性 |
说明 |
AdProperties |
从广告文件获取的当前广告的所有属性的集合。这个集合包含广告文件中的任何自定义属性 |
AlternateText |
获取或设置广告的替代文本 |
ImageUrl |
获取或设置当前广告的图像的路径 |
NavigateUrl |
获取或设置点击当前广告时要到达的页面的路径 |
3.3 使用HTMLInputFile控件接受文件上传
许多时候,你可以让网站的用户将文件上传到你的Web服务器。
你可能想建立一个集中式文档库来存储Microsoft Word文档。
可以使用HTMLInputFile控件允许用户将任何类型的文件从他们的硬盘傻姑娘传到你的网站。可以使用HTMLInputFile控件上传图像、HTML文件、Microsoft word文档、MPEG文件或视频文件。
HTMLInputFile的属性
属性 |
说明 |
Accept |
指定可以上传的文件的MIME类型列表(用逗号分隔)例如image/gif表示GIF图像文件;image/*表示所有类型的图像文件 |
MaxLength |
指定可以在上传文本框中输入的最大字符数 |
PostedFile |
返回用户上传的文件 |
Size |
指出上传文件的大小 |
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> Protected Sub btnUploadFile_Click(ByVal sender As Object, ByVal e As System.EventArgs) inpFileUp.PostedFile.SaveAs("C:"Uploads"NewFile.gif") 'PostedFile属性指向被上传的文件。 '从技术上讲,这个属性指向HttpPostedFile类的实例。 '此处,调用HttpPostedFile类的SaveAs()方法,将上传的文件保存到磁盘上。 End Sub </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" enctype="multipart/form-data" runat="server"> <div> <input id="inpFileUp" type="file" runat="server" /> <%--HTMLInputFile控件是一个HTML控件,而不是Web控件。 如果打算在表单中放一个HTMLInputFile控件,就必须修改表单默认的编码方式enctype="multipart/form-data"--%> <p /> <asp:Button ID="btnUploadFile" Text="Upload File!" runat="server" OnClick="btnUploadFile_Click" /> </div> </form> </body> </html> |
HttpPostedFile属性
属性 |
说明 |
ContentLength |
指定上传的文件的字节数 |
ContentType |
指定上传的文件的MIME内容类型 |
FileName |
指定上传的文件在客户机上的完整路径 |
InputStream |
返回代表上传文件的原始内容的流 |
HttpPostedFile方法
SaveAs——将上传的文件保存到磁盘上
可以使用HttpPostedFile类的属性获取关于上传的文件的更多信息。
4 小结