在本系列之三《asp.net夜话之三:表单和控件》中讲到了HTML服务器控件,HTML服务器控件有如下特点:
(1)HTML服务器控件是建立在HTML控件的基础上,额外增加了一个在当前页面中唯一的ID属性值和一个runat=”server”属性;
(2)HTML服务器控件必须放在服务器端表单中,也就是必须在<form runat=”server” id=”form表单ID”></form>标记之中。
(3)HTML服务器控件最终在Web服务器处会被解释成普通HTML控件标记发送到客户端浏览器。
asp.net服务器控件是微软为了方便开发者开发而推出的一系列控件,它们都以类似<asp:* ID="btnOK" runat="server" …/>的方式出现在Visual Studio 2005的源视图里,*代表了控件名,如<asp:Button ID="btnOK" runat="server" Text="提交" />就表示这是一个Button控件。asp.net服务器控件除了提供HTML服务器控件所能提供的功能之外,还有很多功能更为复杂的控件。这些控件可以分为简单控件、容器控件、数据绑定控件、数据源控件和数据验证控及用户自己根据自己业务需要将一些控件组合在一起组成的用户控件等。
asp.net控件的特点与HTML服务器控件类似,也有如下特点:
(1)asp.net服务器控件必须有一个在当前页面中唯一的ID属性和runat=”server”属性;
(2)asp.net服务器控件必须放在服务器端表单中;
(3)asp.net服务器控件最终会被解释成普通HTML标记发送到客户端浏览器。

 

本文主要介绍以下控件:
Button控件
TextBox控件
Web服务器控件的特殊客户端事件
FileUpload控件
Literal控件
Panel控件
PlaceHolder控件

 

Button控件
Button控件是asp.net开发时最常见的控件之一,我们创建一个页面名为ServerControl.aspx,下面就是这个页面的前台代码:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ServerControl.aspx.cs" Inherits="ServerControl" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.     <table border="0" width="100%">
  11.     <tr><td>
  12.         </td><td></td></tr>
  13.     <tr><td></td><td></td></tr>
  14.     <tr><td></td><td></td></tr>
  15.     <tr><td></td><td></td></tr>
  16.     <tr><td><asp:Button ID="btnOK" runat="server" Text="提交" /></td><td></td></tr>
  17.     </table>
  18.     </div>
  19.     </form>
  20. </body>
  21. </html>

这个页面在客户端一个只有一个提交按钮的页面,我们点击这个按钮的时候页面会刷新,它在客户端浏览器的HTML代码如下:


 

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" >
  3. <head><title>
  4.  无标题页
  5. </title></head>
  6. <body>
  7.     <form name="form1" method="post" action="ServerControl.aspx" id="form1">
  8. <div>
  9. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQ2OTkzNDMyMWRkT/VDzJ0SWn3BqgG/UOUV4Cqu7NY=" />
  10. </div>
  11.     <div>
  12.     <table border="0" width="100%">
  13.     <tr><td>
  14.         </td><td></td></tr>
  15.     <tr><td></td><td></td></tr>
  16.     <tr><td></td><td></td></tr>
  17.     <tr><td></td><td></td></tr>
  18.     <tr><td><input type="submit" name="btnOK" value="提交" id="btnOK" /></td><td></td></tr>
  19.     </table>
  20.     </div>
  21.     
  22. <div>
  23.  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgKFss63DQLdkpmPAbagjAxymGXZUaR5sNMBZHmUjoKd" />
  24. </div></form>
  25. </body>
  26. </html>

可见默认情况下,Button控件被解释成<input type=”submit” …/>形势的提交按钮,并且这个按钮的客户端id(即在HTML代码中的id属性)和我们在服务器端指定的id是一致的。还有一点要说明的是,在设计时表单的代码是“<form id="form1" runat="server">”,到了客户端变成了“<form name="form1" method="post" action="ServerControl.aspx" id="form1">”,这也是幕后的工作,我们的表单发送到客户端时被设置成post提交方式,接收表单数据的页面是当前页面(当前页面就是ServerControl.aspx)。
因为Button控件默认生成HTML的提交按钮,所以点击这个按钮自然就有了提交表单行为,并且默认是提交到当前页面处理。
Button按钮常见属性有如下:

属性名 属性类型 属性说明
CausesValidation bool  指示在单击 Button 控件时是否执行验证
CommandArgument string 该参数会传递到Command 事件
CssClass string 该参数指示控件在客户端呈现的级联样式表 (CSS) 类
Enabled bool 指示是否启用 Web 服务器控件
OnClientClick string Button 控件的 Click 事件时所执行的客户端脚本
Text string 在 Button 控件中显示的文本标题
ValidationGroup string Button 控件回发到服务器时要进行验证的控件组

 

  
Button控件的常见事件

 

事件名 委托类型 事件说明
Click EventHandler 单击Button控件激发的事件
Command CommandEventHandler 单击Button控件激发的事件

 

  
今天要讲的是CommandArgument、CssClass、OnClientClick属性和Click及Command事件。其它如CausesValidation和ValidationGroup会在验证控件部分再具体讲。
CssClass这个属性非常有用,如果是单个按钮我们可以直接设置Button的前景色、背景色及Style属性,可是在大型网站中这么设置非常不方便,并且维护起来非常不方便。试想一下,在一个网站中有数百个甚至数千个Button按钮,有一天客户想改变它们的风格,那么是多么枯燥的一件事情,CssClass就是用来设置控件的css属性的(这个属性很多控件都有),这样在外部css样式文件中改变一下,整个网站的Button控件显示风格全部变化了,非常方便。
OnClientClick这个属性用于一些需要客户端交互的场合,比如点击这个按钮会从数据库删除一些数据,有可能客户无意中点了这个按钮,那么我们可以给用户一次确认的机会,一旦用户吃了秤砣铁了心要删除他只需要确认一下就可以,如果不小心碰上这个按钮还可以点击“否”来取消。有经验的程序员在一些重要操作的时候都会给出这个提示,这个提示其实就是利用javascript的confirm()函数来实现。
Click和Command事件都是单击Button按钮时发生的事件,可是处理它们的委托类型不同,激发Click事件由 EventHandler委托来处理,激发Command事件后由CommandEventHandler委托来处理,看看它们的声明:

  1. public delegate void EventHandler (
  2.  Object sender,
  3.  EventArgs e
  4. )
  5. public delegate void CommandEventHandler (
  6.  Object sender,
  7.  CommandEventArgs e
  8. )

看出区别来了吗?它们都有两个参数,第一个参数表示由哪个控件激发了事件,第二个参数表示发生事件时的一些事件数据。这两个委托第一个参数都是相同的,第二个参数不同,EventArgs这个类不带有任何事件数据(这个委托很常见,不关心事件数据的事件都是用这个委托处理),而CommandEventArgs可以附带事件数据,它有两个重要属性:CommandArgument和CommandName。CommandArgument属性可以附带一些参数信息,CommandName用于设置命名的名称。
下面对刚才的页面添加更多代码,前台代码如下:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ServerControl.aspx.cs" Inherits="ServerControl" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6.     <style type="text/css">
  7.     .zhoufoxcn
  8.     {
  9.     color:#0000C0;
  10.     background-color:Olive;
  11.     border-color:Red;
  12.     border-style:Dotted;
  13.     }
  14.     .redfoxcn
  15.     {
  16.     color:red;
  17.     background-color:Olive;
  18.     border-color:#0000C0;
  19.     border-style:Dotted;
  20.     }
  21.     </style>
  22. </head>
  23. <body>
  24.     <form id="form1" runat="server">
  25.     <div>
  26.     <table border="0" width="100%">
  27.     <tr><td>
  28.         </td><td></td></tr>
  29.     <tr><td></td><td></td></tr>
  30.     <tr><td></td><td></td></tr>
  31.     <tr><td>
  32.         </td><td></td></tr>
  33.     <tr><td><asp:Button ID="btnOK" runat="server" Text="Click" OnClientClick="javascript:return confirm('确认提交?')" OnClick="btnOK_Click" CssClass="zhoufoxcn" /></td><td>
  34.         <asp:Button ID="btnCommand" runat="server"
  35.             Text="Command" OnCommand="btnCommand_Command" CommandArgument="1" CssClass="redfoxcn" /></td></tr>
  36.     </table>
  37.     </div>
  38.     </form>
  39. </body>
  40. </html>

后台cs代码如下:


 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class ServerControl : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     protected void btnOK_Click(object sender, EventArgs e)
  17.     {
  18.         Response.Write("发生了Click事件。");
  19.     }
  20.     protected void btnCommand_Command(object sender, CommandEventArgs e)
  21.     {
  22.         Response.Write("发生了Command事件,事件的数据是:" + e.CommandArgument.ToString());
  23.     }
  24. }

在前台代码中我们定义了css样式,定义了两个css类:zhoufoxcn和redfoxcn。ID为“btnOK”的Button控件的CsssClass属性为zhoufoxcn,它的OnClientClick属性为"javascript:return confirm('确认提交?')",用户在浏览器点击这个按钮的时候会弹出一个“确认提交?”的询问对话框,用户点击“是”提交当前表单,否则不会将表单提交到服务器进行处理,这个控件的OnClick属性值为“btnOK_Click”,“btnOK_Click”是服务器上的一个方法,注意这个服务器方法一定要存在,并且满足EventHandler委托参数类型要求,否则不会编译通过。另外ID为“btnCommand”的Button控件的OnCommand属性为“btnCommand_Command”,这也是一个服务器端方法。给Button控件添加OnClick添加处理方法时双击就可以切换到cs代码,服务器会自动添加相关代码,但是给OnCommand添加相关处理方法时,不能这么做,只能通过在界面中找到该Button控件,在属性栏中点击事件,双击Command右边的空白处,如下图所示:
 
下面是浏览器中的HTML代码:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" >
  3. <head><title>
  4.  无标题页
  5. </title>
  6.     <style type="text/css">
  7.     .zhoufoxcn
  8.     {
  9.     color:#0000C0;
  10.     background-color:Olive;
  11.     border-color:Red;
  12.     border-style:Dotted;
  13.     }
  14.     .redfoxcn
  15.     {
  16.     color:red;
  17.     background-color:Olive;
  18.     border-color:#0000C0;
  19.     border-style:Dotted;
  20.     }
  21.     </style>
  22. </head>
  23. <body>
  24.     <form name="form1" method="post" action="ServerControl.aspx" id="form1">
  25. <div>
  26. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQ3NjkyOTcyMmRkO5nkxzPqNMQvNwHngU2sXldPuhM=" />
  27. </div>
  28.     <div>
  29.     <table border="0" width="100%">
  30.     <tr><td>
  31.         </td><td></td></tr>
  32.     <tr><td></td><td></td></tr>
  33.     <tr><td></td><td></td></tr>
  34.     <tr><td>
  35.         </td><td></td></tr>
  36.     <tr><td><input type="submit" name="btnOK" value="Click" onclick="javascript:return confirm('确认提交?');" id="btnOK" class="zhoufoxcn" /></td><td>
  37.         <input type="submit" name="btnCommand" value="Command" id="btnCommand" class="redfoxcn" /></td></tr>
  38.     </table>
  39.     </div>
  40.     
  41. <div>
  42.  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKfyNPeBgLdkpmPAQLmjabZCHH72VxzRufctQapudcEco8xXEb0" />
  43. </div></form>
  44. </body>
  45. </html>


下面是运行情况:
 
点击“Click”的情况:
 
点击“Command”按钮后的运行情况:
 
需要注意的是:Click事件和Command事件不能同时使用,如果需要事件的数据,那么就用Command事件,然后设置CommandEventArgs属性来附带事件数据,如果不关心事件数据,那么直接用Click属性就行了。

 

TextBox控件
TextBox控件用来提供一个输入框,这个输入框默认是输入单行文本的,但是我们可以设置它的TextMode属性来控制输入框的形式。它可以是以下三个值:
TextMode="SingleLine":用来输入单行文本
TextMode="Password":用来输入密码
TextMode="MultiLine":用来输入多行文本
下面对ServerControl.aspx的前台再做一下改造,代码如下:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ServerControl.aspx.cs" Inherits="ServerControl" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6.     <style type="text/css">
  7.     .zhoufoxcn
  8.     {
  9.     color:#0000C0;
  10.     background-color:Olive;
  11.     border-color:Red;
  12.     border-style:Dotted;
  13.     }
  14.     .redfoxcn
  15.     {
  16.     color:red;
  17.     background-color:Olive;
  18.     border-color:#0000C0;
  19.     border-style:Dotted;
  20.     }
  21.     </style>
  22. </head>
  23. <body>
  24.     <form id="form1" runat="server">
  25.     <div>
  26.     <table border="0" width="100%">
  27.     <tr><td>
  28.         用户名</td><td>
  29.         <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td></tr>
  30.     <tr><td>
  31.         密码</td><td>
  32.         <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox></td></tr>
  33.     <tr><td>
  34.         简单介绍</td><td>
  35.         <asp:TextBox ID="TextBox3" runat="server" TextMode="MultiLine"></asp:TextBox></td></tr>
  36.     <tr><td>
  37.         </td><td></td></tr>
  38.     <tr><td><asp:Button ID="btnOK" runat="server" Text="Click" OnClientClick="javascript:return confirm('确认提交?')" OnClick="btnOK_Click" CssClass="zhoufoxcn" /></td><td>
  39.         <asp:Button ID="btnCommand" runat="server"
  40.             Text="Command" OnCommand="btnCommand_Command" CommandArgument="1" CssClass="redfoxcn" /></td></tr>
  41.     </table>
  42.     </div>
  43.     </form>
  44. </body>
  45. </html>

运行之后,我们在每个文本框都输入“zhoufoxcn”,结果如下:
 
另外TextBox控件还有一个属性:AutoPostBack。这个属性默认是false,即控件的值发生变化时不会自动自动发生提交,如果为true就会自动向服务器提交(当控件失去焦点的时候向服务器提交),并且它还有一个事件TextChanged专门用来处理TextBox中的文本变化的情况的。
再对上面的代码变化一下,设置ID为“txtUserName”的控件的AutoPostBack属性为true,如下:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ServerControl.aspx.cs" Inherits="ServerControl" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6.     <style type="text/css">
  7.     .zhoufoxcn
  8.     {
  9.     color:#0000C0;
  10.     background-color:Olive;
  11.     border-color:Red;
  12.     border-style:Dotted;
  13.     }
  14.     .redfoxcn
  15.     {
  16.     color:red;
  17.     background-color:Olive;
  18.     border-color:#0000C0;
  19.     border-style:Dotted;
  20.     }
  21.     </style>
  22. </head>
  23. <body>
  24.     <form id="form1" runat="server">
  25.     <div>
  26.     <table border="0" width="100%">
  27.     <tr><td>
  28.         用户名</td><td>
  29.         <asp:TextBox ID="txtUserName" runat="server" AutoPostBack="True" OnTextChanged="txtUserName_TextChanged"></asp:TextBox></td></tr>
  30.     <tr><td>
  31.         密码</td><td>
  32.         <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox></td></tr>
  33.     <tr><td>
  34.         简单介绍</td><td>
  35.         <asp:TextBox ID="txtIntroduce" runat="server" TextMode="MultiLine"></asp:TextBox></td></tr>
  36.     <tr><td>
  37.         </td><td></td></tr>
  38.     <tr><td><asp:Button ID="btnOK" runat="server" Text="Click" OnClientClick="javascript:return confirm('确认提交?')" OnClick="btnOK_Click" CssClass="zhoufoxcn" /></td><td>
  39.         <asp:Button ID="btnCommand" runat="server"
  40.             Text="Command" OnCommand="btnCommand_Command" CommandArgument="1" CssClass="redfoxcn" /></td></tr>
  41.     </table>
  42.     </div>
  43.     </form>
  44. </body>
  45. </html>

双击ID为“txtUserName”的这个控件,就会自动产生一个事件,在这个事件中编写处理代码,如下:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class ServerControl : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     protected void btnOK_Click(object sender, EventArgs e)
  17.     {
  18.         Response.Write("发生了Click事件。");
  19.     }
  20.     protected void btnCommand_Command(object sender, CommandEventArgs e)
  21.     {
  22.         Response.Write("发生了Command事件,事件的数据是:" + e.CommandArgument.ToString());
  23.     }
  24.     protected void txtUserName_TextChanged(object sender, EventArgs e)
  25.     {
  26.         Response.Write("当前输入的用户名是:" + txtUserName.Text);
  27.     }
  28. }


当我们在用户名文本框输入用户名,并将光标从用户名文本框移开时,会出现如下情况:
 
也就是当用户光标移开用户名输入框时,会自动提交表单并由它在服务器端定义的方法处理。这样可以及时将反馈显示给用户,不过缺点是需要将整个表单提交给服务器,然后整页面发送到客户端浏览器,降低了服务器的处理效率,也加大了网络数据传输。对一些小型站点可以这么做,如果是大型网站就需要采用Ajax方法来处理了,这也是为什么Visual Studio 2005中默认这个属性为false的原因了。

 

Web服务器控件的特殊客户端事件
我们知道Web服务器控件最终会解释成普通HTML控件到客户端浏览器,比如TextBox这个Web服务器控件最终在客户端浏览器呈现为文本输入框控件、密码输入框控件或者文本框控件,这个由TextBox的TextMode属性来决定。用Web服务器控件有一个缺点就是很多时候我们没有办法获得它解释成客户端控件之后的客户端事件。
下面是文本输入框控件在客户端的事件(下图截取自Dreamweaver 8编辑器):
 
我们可以看到文本框控件有很多客户端事件。再看看对应的TextBox控件拥有的事件智能提示:
 
从上面的截图中可以看到TextBox控件也拥有很多事件,但是这些事件不是客户端的,而是服务器端的。
我们先写一个HTML文件,代码如下:


 

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
  5. <title>HTML控件的客户端事件</title>
  6. <script language="javascript">
  7. //下面的方法根据敲击键盘的ASCII码值来判断是否敲击了数字键
  8. //数字键的ASCII码值介于48到57之间,分别对应数字0到9
  9. //当方法返回true的时候敲入的字符才能显示
  10. function judgeNumber(code)
  11. {
  12.  //alert(code);
  13.  if(code>=48&<=57)
  14.  {
  15.   return true;
  16.  }
  17.  else
  18.  {
  19.   return false;
  20.  }
  21. }
  22. //英文字母A-Z的ASCII码值65-90,a-z的ASCII码值是97-122
  23. //当方法返回true的时候敲入的字符才能显示
  24. function judgeChar(code)
  25. {
  26.  //alert(code);
  27.  if((code>=65&<=90)||(code>=97&<=122))
  28.  {
  29.   return true;
  30.  }
  31.  else
  32.  {
  33.   return false;
  34.  }
  35. }
  36. </script>
  37. </head>
  38. <body>
  39. <form>
  40. 数字:<input type="text" name="userName" onkeypress="return judgeNumber(event.keyCode);" /><br/>
  41. 字母:<input type="text" name="password" onkeypress="return judgeChar(event.keyCode);" />
  42. </form>
  43. </body>
  44. </html>

这个页面的运行效果如下:
 
上面的页面效果是:第一个文本框只能输入数字,第二个文本框只能大小写字母。我们能知道TextBox如果TextMode是SingleLine的话(这个是默认值,无需手动添加),最后在客户端浏览器也是普通文本框,那么我们可不可以给TextBox控件加上上面的效果呢?答案是可以的。
在Visual Studio 2005新建一个名为“TextBoxClient”页面窗体,在源视图中粘贴如下代码:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TextBoxClient.aspx.cs" Inherits="TextBoxClient" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6.     <script language="javascript" type="text/javascript">
  7. //下面的方法根据敲击键盘的ASCII码值来判断是否敲击了数字键
  8. //数字键的ASCII码值介于48到57之间,分别对应数字0到9
  9. //当方法返回true的时候敲入的字符才能显示
  10. function judgeNumber(code)
  11. {
  12.  //alert(code);
  13.  if(code>=48&<=57)
  14.  {
  15.   return true;
  16.  }
  17.  else
  18.  {
  19.   return false;
  20.  }
  21. }
  22. //英文字母A-Z的ASCII码值65-90,a-z的ASCII码值是97-122
  23. //当方法返回true的时候敲入的字符才能显示
  24. function judgeChar(code)
  25. {
  26.  //alert(code);
  27.  if((code>=65&<=90)||(code>=97&<=122))
  28.  {
  29.   return true;
  30.  }
  31.  else
  32.  {
  33.   return false;
  34.  }
  35. }
  36. </script>
  37. </head>
  38. <body>
  39.     <form id="form1" runat="server">
  40.     <div>
  41.         数字:<asp:TextBox ID="TextBox1" runat="server" onkeypress="return judgeNumber(event.keyCode);"></asp:TextBox><br />
  42.         字母:<asp:TextBox ID="TextBox2" runat="server" onkeypress="return judgeChar(event.keyCode);"></asp:TextBox></div>
  43.     </form>
  44. </body>
  45. </html>

上面的程序在客户端的最终效果和用普通HTML控件的效果一样,只不过在Visual Studio 2005源视图会得到如图所示的提示:
 
好在只是绿色波浪线,表示警告,所以还是能通过编译并且能运行的,如果是红色波浪线表示是错误,就没有办法运行了。对于Visual Studio 2005来说,它并不认识那些javascript客户端事件,尽管警告,不过它还是照原样输出了,到了客户端就成了普通HTML控件,浏览器能识别这些,所以能正确运行。

 

FileUpload控件
FileUpload控件是一个很重要的控件,它被Web服务器最终解释为形如“<input type=”file”…/>”这样的普通HTML控件。
它有如下常见属性:

 

属性名 数据类型 说明
FileBytes byte[] 上传的文件内容的字节数组表示形式
FileContent Stream 上传文件的数据流
FileName string 上传文件在客户端的名字
HasFile bool  指示是否上传了文件
PostedFile HttpPostedFile 获取文件基础的HttpPostedFile对象

 

  
这个HttpPostedFile对象能帮我们做很多工作,它也有一些有用的常见属性:

 

属性名 数据类型 说明
ContentLength int 上传的文件内容的字节长度
ContentType string 上传文件的MIME 内容类型
FileName string 上传文件的在客户端的名字
InputStream Stream 指向上传文件的Stream对象

  

 

FileUpload控件还有一个void SaveAs (string filename)的方法,这个方法用于将上传的文件保存到服务器上。一般来说,使用FileUpload控件上传文件一般有如下几个步骤:
(1)利用HasFile属性判断是否上传了文件。
(2)在服务器上指定一个物理路径,并检查这个物理路径是否存在,如果不存在则先创建。
(3)指定上传文件在服务器上的上传路径,利用SaveAs()保存上传的文件。这一步还可以做一些其它检查工作,比如检查上传的文件格式是否符合要求或文件内容大小是否符合要求。
(4)将相对路径或者URL地址保存起来,以便客户访问或者下载。
这里要着重强调的是:我们保存上传的时候保存文件用的是物理路径,但是要保存的、日后客户端能访问得到的却是相对路径或者URL地址。
下面是一个简单的例子,这个页面叫Upload.aspx,它的源视图代码如下:


 

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Upload.aspx.cs" Inherits="Upload" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>文件上传的例子</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.         <asp:FileUpload ID="fileUpload" runat="server" />
  11.         <asp:Button ID="btnUpload" runat="server" OnClick="btnUpload_Click" Text="上传" />
  12.         <asp:Literal ID="literal" runat="server"></asp:Literal></div>
  13.     </form>
  14. </body>
  15. </html>

后台cs代码如下:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class Upload : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     protected void btnUpload_Click(object sender, EventArgs e)
  17.     {
  18.         //判断是否上传了文件
  19.         if (fileUpload.HasFile)
  20.         {
  21.             //指定上传文件在服务器上的保存路径
  22.             string savePath = Server.MapPath("~/upload/");
  23.             //检查服务器上是否存在这个物理路径,如果不存在则创建
  24.             if (!System.IO.Directory.Exists(savePath))
  25.             {
  26.                 //需要注意的是,需要对这个物理路径有足够的权限,否则会报错
  27.                 //另外,这个路径应该是在网站之下,而将网站部署在C盘却把上传文件保存在D盘
  28.                 System.IO.Directory.CreateDirectory(savePath);
  29.             }
  30.             savePath = savePath + "//" + fileUpload.FileName;
  31.             fileUpload.SaveAs(savePath);//保存文件
  32.             //不过需要注意的是,在客户端访问却需要指定的是URL地址,而不是在服务器上的物理地址
  33.             literal.Text = string.Format("<a href='upload/{0}'>upload/{0}</a>", fileUpload.FileName);
  34.         }
  35.     }
  36. }

 以下是程序运行结果:


上传文件之后的效果:
 
因为我上传了一个proc.txt的文件,所以最后的URL地址是:upload/proc.txt,点击这个超级链接能打开刚刚上传的文件查看其内容,如下图:
 
注意:对于有些文件,如rar格式的,点击之后则会出现下载提示而不是直接在浏览器打开。

 

带图片预览功能的FileUpload控件
通过上面的讲述,我们知道一些web服务器控件在vs2005下没有javascript客户端事件的提示,不过只要我们确信这个事件对应的HTML控件确实有,我们可以自行添加的,下面我们就来做一个让FileUpload控件带有图片预览功能的例子。
因为这里不涉及到上传后如何保存,只是仅仅在用户选择了要上传的文件时或者用户将鼠标移动到上传控件上时,如果上传的文件是图片文件,我们就显示这个图片的预览效果5分钟,然后消失。以下是程序代码(前台代码,保存代码和上面的例子一样,所以没有写后台cs代码):

 

 

  1. <%@ Page Language="C#" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <script runat="server">
  4. </script>
  5. <html xmlns="http://www.w3.org/1999/xhtml" >
  6. <head runat="server">
  7.     <title>上传图片预览实例</title>
  8.     <script type="text/javascript" language="javascript">
  9. //如果用户选择了图片,则显示图片的预览效果
  10. function previewImage()
  11. {
  12.   var x = document.getElementById("file");
  13.   if(!x || !x.value)//如果没有选择上传文件
  14.   {
  15.      return;
  16.    }
  17.     var patn = //.jpg$|/.jpeg$|/.gif$/i;
  18.     if(patn.test(x.value))//如果上传文件的后缀是.jpg或.jpeg或.gif
  19.     {    
  20.         var y = document.getElementById("img");
  21.         if(y)
  22.         {      
  23.             y.src = 'file://localhost/' + x.value;
  24.             y.style.display="block"
  25.         }
  26.         else
  27.         {
  28.             var img=document.createElement('img');      
  29.             img.setAttribute('src','file://localhost/'+x.value);      
  30.             img.setAttribute('width','120');      
  31.             img.setAttribute('height','90');      
  32.             img.setAttribute('id','img');      
  33.             document.getElementById('form1').appendChild(img);      
  34.         }
  35.         setTimeout("hidden()",5000); //5秒之后执行隐藏图片的javascript方法
  36.     }
  37.     else
  38.     {    
  39.         alert("您选择的似乎不是图像文件。");  
  40.     }
  41. }
  42. //隐藏照片
  43. function hidden()
  44. {
  45.     var y = document.getElementById("img");
  46.     if(y)
  47.     {
  48.         document.getElementById('img').style.display="none";
  49.     }
  50. }
  51. </script>
  52. </head>
  53. <body>
  54.     <form id="form1" runat="server">
  55.     <div>
  56.          <asp:FileUpload ID="file" runat="server" onchange="previewImage()" onmouseover="previewImage()" />
  57.         <asp:Button ID="btnUpload" runat="server" Text="上传" /></div>
  58.     </form>
  59. </body>
  60. </html>

说明一下,在这个页面里form表单的id是form1,上传控件的id是file,所以在客户端用到了document.getElementById()这个方法来获取相关的控件的属性值,并且通过javascript脚本动态添加了一个<img id=”img”>的控件,然后我们操纵它的src属性来决定显示哪张图片,利用它的style.display属性来决定是否显示。
以下预览时的效果:

预览5秒钟之后,不再带有预览功能的效果:

注意:如果我们要上传文件,需要给表单增加enctype="multipart/form-data"属性,如果我们使用了FileUpload控件时,生成HTML代码时表单会自动加上这个属性。

 

Literal控件
Literal控件是一个类似于Label控件的控件,都是用来呈现文字的。前面我说过,虽然通过Response.Write()方法可以直接输出文字,但是这样输出的文字有可能在<html></html>标记之外,破坏了网页的结构,使之不再符合XHTML标准。
对于静态文字,我们可以直接在HTML代码中书写即可,而没有必要使用Literal 控件或 Label 控件。但是在某些情况下我们却希望在某个位置设置一些文字,那么我们就可以先在期望输出文字的地方放置一个Literal控件,将来在程序代码中根据程序逻辑动态设置Literal控件的Text属性来控制要输出的文字。
尽管在某种程度上,Literal 控件用法与 Label 控件用法类似,但是不同的是 Literal 控件不能用于将css样式应用于显示的文本。
另外Literal 控件还有一个Mode属性,它用来控制如何呈现Literal 控件中的内容。这个属性是一个枚举,有三个枚举值:
PassThrough:直接呈现Literal 控件中的内容。
Encode:控件的内容转换为 HTML 编码的字符串。
Transform:从控件的内容中移除不受支持的标记语言元素。如果 Literal 控件在支持 HTML 或 XHTML 的浏览器上呈现,则不会修改该控件的内容。
举例说明,假如Literal的Text属性为“<abc>http://blog.csdn.net/zhoufoxcn</abc>”,即如下代码:

  1.  <table border="1" width="600" cellpadding="1" cellspacing="1">
  2.         <tr><td>
  3.             
  4.                 Mode</td><td>
  5.           效果</td></tr>
  6.         <tr><td>
  7.             PassThrough</td><td>
  8.             <asp:Literal ID="Literal1" runat="server" Mode="PassThrough" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
  9.         <tr><td>
  10.             Encode</td><td>
  11.             <asp:Literal ID="Literal2" runat="server" Mode="Encode" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
  12.         <tr><td>
  13.             Transform</td><td>
  14.             <asp:Literal ID="Literal3" runat="server" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
  15.         </table>

在浏览器的效果如下:
 
它们生成相关HTML代码如下:

  1. <table border="1" width="600" cellpadding="1" cellspacing="1">
  2.         <tr><td>
  3.             
  4.                 Mode</td><td>
  5.           效果</td></tr>
  6.         <tr><td>
  7.             PassThrough</td><td>
  8.             <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
  9.         <tr><td>
  10.             Encode</td><td>
  11.             <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
  12.         <tr><td>
  13.             Transform</td><td>
  14.             <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
  15.         </table>

在浏览器中查看的时候,PassThrough 和Transform模式的效果是一样的,但是如果用智能设备查看的时候,PassThrough在客户端的代码仍然是<abc>http://blog.csdn.net/zhoufoxcn</abc>,而Transform模式在客户端的代码是http://blog.csdn.net/zhoufoxcn,要注意这个差别,Literal控件Mode属性默认是Transform模式。

 

Panel控件
Panel控件是一个容器控件,用来存储一组容器控件,它常用来存放一组业务逻辑上相似的控件组。下面看一个例子,这个例子里会根据用户选择的性别动态决定对象配偶的名字,如果是男性则让填写妻子的名字,如果是女性则让填写丈夫的名字,源视图代码如下:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="PanelDemo.aspx.cs" Inherits="PanelDemo" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" >
  4. <head runat="server">
  5.     <title>无标题页</title>
  6. </head>
  7. <body>
  8.     <form id="form1" runat="server">
  9.     <div>
  10.         性别:<asp:RadioButton ID="rbMale" runat="server" AutoPostBack="True" Checked="True" OnCheckedChanged="RadioButton_CheckedChanged" Text="男" GroupName="sex" />
  11.         <asp:RadioButton ID="rbFemale" runat="server" Text="女" AutoPostBack="True" GroupName="sex" OnCheckedChanged="RadioButton_CheckedChanged" /><br />
  12.         <asp:Panel ID="pMale" runat="server" Height="50px" Width="125px">
  13.         妻子姓名:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
  14.         </asp:Panel>
  15.         </div>
  16.         <asp:Panel ID="pFemale" runat="server" Height="50px" Width="125px" Visible="False">
  17.         丈夫姓名:<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
  18.         </asp:Panel>
  19.     </form>
  20. </body>
  21. </html>


在这里我们用了两个RadioButton控件,并且设置了它们的GroupName属性都为“sex”,表示这两个RadioButton属于一个分组,它们之中只能有一个处于选中状态,另外我们还设置了这两个RadioButton控件的AutoPostBack属性都为“true”,表示当它们的选择状态发生变化的时候,将会自动提交到服务器进行处理,并且对于它们在服务器端的处理都都使用了同一个方法RadioButton_CheckedChanged,后台代码如下:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. public partial class PanelDemo : System.Web.UI.Page
  12. {
  13.     protected void Page_Load(object sender, EventArgs e)
  14.     {
  15.     }
  16.     protected void RadioButton_CheckedChanged(object sender, EventArgs e)
  17.     {
  18.         //如果选择的性别是“男”,则让填写妻子的姓名
  19.         if (rbMale.Checked)
  20.         {
  21.             pMale.Visible = true;
  22.             pFemale.Visible = false;
  23.         }
  24.         else//否则让填写丈夫的姓名
  25.         {
  26.             pMale.Visible = false;
  27.             pFemale.Visible = true;
  28.         }
  29.     }
  30. }


程序的运行效果如下:
 
选择“女”之后的变化:
 
我们可以查看Panel控件生成的代码:

  1. <div>
  2.         性别:<input id="rbMale" type="radio" name="sex" value="rbMale" checked="checked" /><label for="rbMale"></label>
  3.         <input id="rbFemale" type="radio" name="sex" value="rbFemale" onclick="javascript:setTimeout('__doPostBack(/'rbFemale/',/'/')', 0)" /><label for="rbFemale"></label><br />
  4.         <div id="pMale" style="height:50px;width:125px;">
  5.         妻子姓名:<input name="TextBox1" type="text" id="TextBox1" />
  6.         
  7. </div>
  8.         </div>
  9.         
  10.     
  11. <div>

上面的代码是当选择“男”的时候生成的代码,可见对于Panel控件在客户端的代码为一个<div>标记。

 

PlaceHolder控件
PlaceHolder控件控件的作用和Panel控件的作用非常类似,也是用作容器控件,不过控件本身在客户端不产生任何可见HTML标记。
PlaceHolder控件有一个Controls属性,这个属性表示这个容器控件容纳的控件的集合,Controls属性是ControlCollection类的一个实例,这个类用Add()方法向集合中增加控件,用Remove()删除控件,还有一个Count属性表示这个集合中总共有多少个控件。

下面是一个PlaceHolder控件用法的例子,为了简单起见,我没有采用代码和页面分离的模式,代码如下:


 

  1. <%@ Page Language="C#" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <script runat="server">
  4.     protected void Page_Load(object sender, EventArgs e)
  5.     {
  6.         Button btn = new Button();
  7.         btn.Text = "动态添加的控件";
  8.         btn.Click += new EventHandler(btn_Click);//给动态添加的Button的单击事件增加服务器端方法
  9.         PlaceHolder1.Controls.Add(btn);
  10.     }
  11.     public void btn_Click(object sender, EventArgs e)
  12.     {
  13.         Literal l = new Literal();
  14.         l.Text = "PlaceHolder1控件总共容纳了" + PlaceHolder1.Controls.Count + "个控件";
  15.         PlaceHolder1.Controls.Add(l);
  16.     }
  17. </script>
  18. <html xmlns="http://www.w3.org/1999/xhtml" >
  19. <head runat="server">
  20.     <title>无标题页</title>
  21. </head>
  22. <body>
  23.     <form id="form1" runat="server">
  24.     <div>
  25.         <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
  26.     
  27.     </div>
  28.     </form>
  29. </body>
  30. </html>

程序的运行结果:
 
点击按钮之后的效果:
 
在没有点击按钮之前客户端浏览器得到的HTML代码如下:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" >
  3. <head><title>
  4.  无标题页
  5. </title></head>
  6. <body>
  7.     <form name="form1" method="post" action="PlaceHolderDemo.aspx" id="form1">
  8. <div>
  9. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTM2NTY5NjE1NWRkDxPVOfW9ygVx0MnTmn1nNCXGfWY=" />
  10. </div>
  11.     <div>
  12.         <input type="submit" name="ctl02" value="动态添加的控件" />PlaceHolder1控件总共容纳了1个控件
  13.     
  14.     </div>
  15.     
  16. <div>
  17.  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLhoKDXAwKfwImNCxlfxrs8MWJR7ujk/rFzZ1UfCrph" />
  18. </div></form>
  19. </body>
  20. </html>

小结:Panel和PlaceHolder作为控件的容器,在很多地方是相似的,不同的是PlaceHolder不会在客户端产生任何可见的输出,而Panel还可以设置背景图片等。
Label和Literal控件常用来显示文字(也可以成为文本的容器哦),在很多地方是相似的,不过不能设置Literal的客户端css样式,并且Literal对显示的文本的控制能力更灵活一些,利用Mode属性可以方便地显示HTML代码。

posted on 2013-12-30 17:22  初生牛犊不怕虎  阅读(272)  评论(0编辑  收藏  举报