asp.net夜話之六:asp.net基本控件
在本系列之三《asp.net夜話之三:表單和控件》中講到了HTML服務(wù)器控件,HTML服務(wù)器控件有如下特點:
(1)HTML服務(wù)器控件是建立在HTML控件的基礎(chǔ)上,額外增加了一個在當(dāng)前頁面中唯一的ID屬性值和一個runat=”server”屬性;
(2)HTML服務(wù)器控件必須放在服務(wù)器端表單中,也就是必須在<form runat=”server” id=”form表單ID”></form>標(biāo)記之中。
(3)HTML服務(wù)器控件最終在Web服務(wù)器處會被解釋成普通HTML控件標(biāo)記發(fā)送到客戶端瀏覽器。
asp.net服務(wù)器控件是微軟為了方便開發(fā)者開發(fā)而推出的一系列控件,它們都以類似<asp:* ID='btnOK' runat='server' …/>的方式出現(xiàn)在Visual Studio 2005的源視圖里,*代表了控件名,如<asp:Button ID='btnOK' runat='server' Text='提交' />就表示這是一個Button控件。asp.net服務(wù)器控件除了提供HTML服務(wù)器控件所能提供的功能之外,還有很多功能更為復(fù)雜的控件。這些控件可以分為簡單控件、容器控件、數(shù)據(jù)綁定控件、數(shù)據(jù)源控件和數(shù)據(jù)驗證控及用戶自己根據(jù)自己業(yè)務(wù)需要將一些控件組合在一起組成的用戶控件等。
asp.net控件的特點與HTML服務(wù)器控件類似,也有如下特點:
(1)asp.net服務(wù)器控件必須有一個在當(dāng)前頁面中唯一的ID屬性和runat=”server”屬性;
(2)asp.net服務(wù)器控件必須放在服務(wù)器端表單中;
(3)asp.net服務(wù)器控件最終會被解釋成普通HTML標(biāo)記發(fā)送到客戶端瀏覽器。
本文主要介紹以下控件:
Button控件
TextBox控件
Web服務(wù)器控件的特殊客戶端事件
FileUpload控件
Literal控件
Panel控件
PlaceHolder控件
Button控件
Button控件是asp.net開發(fā)時最常見的控件之一,我們創(chuàng)建一個頁面名為ServerControl.aspx,下面就是這個頁面的前臺代碼:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='ServerControl.aspx.cs' Inherits='ServerControl' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
</head>
<body>
<form id='form1' runat='server'>
<div>
<table border='0' width='100%'>
<tr><td>
</td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td><asp:Button ID='btnOK' runat='server' Text='提交' /></td><td></td></tr>
</table>
</div>
</form>
</body>
</html>
這個頁面在客戶端一個只有一個提交按鈕的頁面,我們點擊這個按鈕的時候頁面會刷新,它在客戶端瀏覽器的HTML代碼如下:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head><title>
無標(biāo)題頁
</title></head>
<body>
<form name='form1' method='post' action='ServerControl.aspx' id='form1'>
<div>
<input type='hidden' name='__VIEWSTATE' id='__VIEWSTATE' value='/wEPDwUKMTQ2OTkzNDMyMWRkT/VDzJ0SWn3BqgG/UOUV4Cqu7NY=' />
</div>
<div>
<table border='0' width='100%'>
<tr><td>
</td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td><input type='submit' name='btnOK' value='提交' id='btnOK' /></td><td></td></tr>
</table>
</div>
<div>
<input type='hidden' name='__EVENTVALIDATION' id='__EVENTVALIDATION' value='/wEWAgKFss63DQLdkpmPAbagjAxymGXZUaR5sNMBZHmUjoKd' />
</div></form>
</body>
</html>
可見默認(rèn)情況下,Button控件被解釋成<input type=”submit” …/>形勢的提交按鈕,并且這個按鈕的客戶端id(即在HTML代碼中的id屬性)和我們在服務(wù)器端指定的id是一致的。還有一點要說明的是,在設(shè)計時表單的代碼是“<form id='form1' runat='server'>”,到了客戶端變成了“<form name='form1' method='post' action='ServerControl.aspx' id='form1'>”,這也是幕后的工作,我們的表單發(fā)送到客戶端時被設(shè)置成post提交方式,接收表單數(shù)據(jù)的頁面是當(dāng)前頁面(當(dāng)前頁面就是ServerControl.aspx)。
因為Button控件默認(rèn)生成HTML的提交按鈕,所以點擊這個按鈕自然就有了提交表單行為,并且默認(rèn)是提交到當(dāng)前頁面處理。
Button按鈕常見屬性有如下:
屬性名 | 屬性類型 | 屬性說明 |
CausesValidation | bool | 指示在單擊 Button 控件時是否執(zhí)行驗證 |
CommandArgument | string | 該參數(shù)會傳遞到Command 事件 |
CssClass | string | 該參數(shù)指示控件在客戶端呈現(xiàn)的級聯(lián)樣式表 (CSS) 類 |
Enabled | bool | 指示是否啟用 Web 服務(wù)器控件 |
OnClientClick | string | Button 控件的 Click 事件時所執(zhí)行的客戶端腳本 |
Text | string | 在 Button 控件中顯示的文本標(biāo)題 |
ValidationGroup | string | Button 控件回發(fā)到服務(wù)器時要進(jìn)行驗證的控件組 |
Button控件的常見事件
事件名 | 委托類型 | 事件說明 |
Click | EventHandler | 單擊Button控件激發(fā)的事件 |
Command | CommandEventHandler | 單擊Button控件激發(fā)的事件 |
今天要講的是CommandArgument、CssClass、OnClientClick屬性和Click及Command事件。其它如CausesValidation和ValidationGroup會在驗證控件部分再具體講。
CssClass這個屬性非常有用,如果是單個按鈕我們可以直接設(shè)置Button的前景色、背景色及Style屬性,可是在大型網(wǎng)站中這么設(shè)置非常不方便,并且維護(hù)起來非常不方便。試想一下,在一個網(wǎng)站中有數(shù)百個甚至數(shù)千個Button按鈕,有一天客戶想改變它們的風(fēng)格,那么是多么枯燥的一件事情,CssClass就是用來設(shè)置控件的css屬性的(這個屬性很多控件都有),這樣在外部css樣式文件中改變一下,整個網(wǎng)站的Button控件顯示風(fēng)格全部變化了,非常方便。
OnClientClick這個屬性用于一些需要客戶端交互的場合,比如點擊這個按鈕會從數(shù)據(jù)庫刪除一些數(shù)據(jù),有可能客戶無意中點了這個按鈕,那么我們可以給用戶一次確認(rèn)的機會,一旦用戶吃了秤砣鐵了心要刪除他只需要確認(rèn)一下就可以,如果不小心碰上這個按鈕還可以點擊“否”來取消。有經(jīng)驗的程序員在一些重要操作的時候都會給出這個提示,這個提示其實就是利用javascript的confirm()函數(shù)來實現(xiàn)。
Click和Command事件都是單擊Button按鈕時發(fā)生的事件,可是處理它們的委托類型不同,激發(fā)Click事件由 EventHandler委托來處理,激發(fā)Command事件后由CommandEventHandler委托來處理,看看它們的聲明:
public delegate void EventHandler (
Object sender,
EventArgs e
)
public delegate void CommandEventHandler (
Object sender,
CommandEventArgs e
)
看出區(qū)別來了嗎?它們都有兩個參數(shù),第一個參數(shù)表示由哪個控件激發(fā)了事件,第二個參數(shù)表示發(fā)生事件時的一些事件數(shù)據(jù)。這兩個委托第一個參數(shù)都是相同的,第二個參數(shù)不同,EventArgs這個類不帶有任何事件數(shù)據(jù)(這個委托很常見,不關(guān)心事件數(shù)據(jù)的事件都是用這個委托處理),而CommandEventArgs可以附帶事件數(shù)據(jù),它有兩個重要屬性:CommandArgument和CommandName。CommandArgument屬性可以附帶一些參數(shù)信息,CommandName用于設(shè)置命名的名稱。
下面對剛才的頁面添加更多代碼,前臺代碼如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='ServerControl.aspx.cs' Inherits='ServerControl' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
<style type='text/css'>
.zhoufoxcn
{
color:#0000C0;
background-color:Olive;
border-color:Red;
border-style:Dotted;
}
.redfoxcn
{
color:red;
background-color:Olive;
border-color:#0000C0;
border-style:Dotted;
}
</style>
</head>
<body>
<form id='form1' runat='server'>
<div>
<table border='0' width='100%'>
<tr><td>
</td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td>
</td><td></td></tr>
<tr><td><asp:Button ID='btnOK' runat='server' Text='Click' OnClientClick='javascript:return confirm('確認(rèn)提交?')' OnClick='btnOK_Click' CssClass='zhoufoxcn' /></td><td>
<asp:Button ID='btnCommand' runat='server'
Text='Command' OnCommand='btnCommand_Command' CommandArgument='1' CssClass='redfoxcn' /></td></tr>
</table>
</div>
</form>
</body>
</html>
后臺cs代碼如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class ServerControl : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnOK_Click(object sender, EventArgs e)
{
Response.Write('發(fā)生了Click事件。');
}
protected void btnCommand_Command(object sender, CommandEventArgs e)
{
Response.Write('發(fā)生了Command事件,事件的數(shù)據(jù)是:' + e.CommandArgument.ToString());
}
}
在前臺代碼中我們定義了css樣式,定義了兩個css類:zhoufoxcn和redfoxcn。ID為“btnOK”的Button控件的CsssClass屬性為zhoufoxcn,它的OnClientClick屬性為'javascript:return confirm('確認(rèn)提交?')',用戶在瀏覽器點擊這個按鈕的時候會彈出一個“確認(rèn)提交?”的詢問對話框,用戶點擊“是”提交當(dāng)前表單,否則不會將表單提交到服務(wù)器進(jìn)行處理,這個控件的OnClick屬性值為“btnOK_Click”,“btnOK_Click”是服務(wù)器上的一個方法,注意這個服務(wù)器方法一定要存在,并且滿足EventHandler委托參數(shù)類型要求,否則不會編譯通過。另外ID為“btnCommand”的Button控件的OnCommand屬性為“btnCommand_Command”,這也是一個服務(wù)器端方法。給Button控件添加OnClick添加處理方法時雙擊就可以切換到cs代碼,服務(wù)器會自動添加相關(guān)代碼,但是給OnCommand添加相關(guān)處理方法時,不能這么做,只能通過在界面中找到該Button控件,在屬性欄中點擊事件,雙擊Command右邊的空白處,如下圖所示:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head><title>
無標(biāo)題頁
</title>
<style type='text/css'>
.zhoufoxcn
{
color:#0000C0;
background-color:Olive;
border-color:Red;
border-style:Dotted;
}
.redfoxcn
{
color:red;
background-color:Olive;
border-color:#0000C0;
border-style:Dotted;
}
</style>
</head>
<body>
<form name='form1' method='post' action='ServerControl.aspx' id='form1'>
<div>
<input type='hidden' name='__VIEWSTATE' id='__VIEWSTATE' value='/wEPDwUKMTQ3NjkyOTcyMmRkO5nkxzPqNMQvNwHngU2sXldPuhM=' />
</div>
<div>
<table border='0' width='100%'>
<tr><td>
</td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td>
</td><td></td></tr>
<tr><td><input type='submit' name='btnOK' value='Click' onclick='javascript:return confirm('確認(rèn)提交?');' id='btnOK' class='zhoufoxcn' /></td><td>
<input type='submit' name='btnCommand' value='Command' id='btnCommand' class='redfoxcn' /></td></tr>
</table>
</div>
<div>
<input type='hidden' name='__EVENTVALIDATION' id='__EVENTVALIDATION' value='/wEWAwKfyNPeBgLdkpmPAQLmjabZCHH72VxzRufctQapudcEco8xXEb0' />
</div></form>
</body>
</html>
下面是運行情況:
TextBox控件
TextBox控件用來提供一個輸入框,這個輸入框默認(rèn)是輸入單行文本的,但是我們可以設(shè)置它的TextMode屬性來控制輸入框的形式。它可以是以下三個值:
TextMode='SingleLine':用來輸入單行文本
TextMode='Password':用來輸入密碼
TextMode='MultiLine':用來輸入多行文本
下面對ServerControl.aspx的前臺再做一下改造,代碼如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='ServerControl.aspx.cs' Inherits='ServerControl' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
<style type='text/css'>
.zhoufoxcn
{
color:#0000C0;
background-color:Olive;
border-color:Red;
border-style:Dotted;
}
.redfoxcn
{
color:red;
background-color:Olive;
border-color:#0000C0;
border-style:Dotted;
}
</style>
</head>
<body>
<form id='form1' runat='server'>
<div>
<table border='0' width='100%'>
<tr><td>
用戶名</td><td>
<asp:TextBox ID='txtUserName' runat='server'></asp:TextBox></td></tr>
<tr><td>
密碼</td><td>
<asp:TextBox ID='txtPassword' runat='server' TextMode='Password'></asp:TextBox></td></tr>
<tr><td>
簡單介紹</td><td>
<asp:TextBox ID='TextBox3' runat='server' TextMode='MultiLine'></asp:TextBox></td></tr>
<tr><td>
</td><td></td></tr>
<tr><td><asp:Button ID='btnOK' runat='server' Text='Click' OnClientClick='javascript:return confirm('確認(rèn)提交?')' OnClick='btnOK_Click' CssClass='zhoufoxcn' /></td><td>
<asp:Button ID='btnCommand' runat='server'
Text='Command' OnCommand='btnCommand_Command' CommandArgument='1' CssClass='redfoxcn' /></td></tr>
</table>
</div>
</form>
</body>
</html>
運行之后,我們在每個文本框都輸入“zhoufoxcn”,結(jié)果如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='ServerControl.aspx.cs' Inherits='ServerControl' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
<style type='text/css'>
.zhoufoxcn
{
color:#0000C0;
background-color:Olive;
border-color:Red;
border-style:Dotted;
}
.redfoxcn
{
color:red;
background-color:Olive;
border-color:#0000C0;
border-style:Dotted;
}
</style>
</head>
<body>
<form id='form1' runat='server'>
<div>
<table border='0' width='100%'>
<tr><td>
用戶名</td><td>
<asp:TextBox ID='txtUserName' runat='server' AutoPostBack='True' OnTextChanged='txtUserName_TextChanged'></asp:TextBox></td></tr>
<tr><td>
密碼</td><td>
<asp:TextBox ID='txtPassword' runat='server' TextMode='Password'></asp:TextBox></td></tr>
<tr><td>
簡單介紹</td><td>
<asp:TextBox ID='txtIntroduce' runat='server' TextMode='MultiLine'></asp:TextBox></td></tr>
<tr><td>
</td><td></td></tr>
<tr><td><asp:Button ID='btnOK' runat='server' Text='Click' OnClientClick='javascript:return confirm('確認(rèn)提交?')' OnClick='btnOK_Click' CssClass='zhoufoxcn' /></td><td>
<asp:Button ID='btnCommand' runat='server'
Text='Command' OnCommand='btnCommand_Command' CommandArgument='1' CssClass='redfoxcn' /></td></tr>
</table>
</div>
</form>
</body>
</html>
雙擊ID為“txtUserName”的這個控件,就會自動產(chǎn)生一個事件,在這個事件中編寫處理代碼,如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class ServerControl : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnOK_Click(object sender, EventArgs e)
{
Response.Write('發(fā)生了Click事件。');
}
protected void btnCommand_Command(object sender, CommandEventArgs e)
{
Response.Write('發(fā)生了Command事件,事件的數(shù)據(jù)是:' + e.CommandArgument.ToString());
}
protected void txtUserName_TextChanged(object sender, EventArgs e)
{
Response.Write('當(dāng)前輸入的用戶名是:' + txtUserName.Text);
}
}
當(dāng)我們在用戶名文本框輸入用戶名,并將光標(biāo)從用戶名文本框移開時,會出現(xiàn)如下情況:
Web服務(wù)器控件的特殊客戶端事件
我們知道Web服務(wù)器控件最終會解釋成普通HTML控件到客戶端瀏覽器,比如TextBox這個Web服務(wù)器控件最終在客戶端瀏覽器呈現(xiàn)為文本輸入框控件、密碼輸入框控件或者文本框控件,這個由TextBox的TextMode屬性來決定。用Web服務(wù)器控件有一個缺點就是很多時候我們沒有辦法獲得它解釋成客戶端控件之后的客戶端事件。
下面是文本輸入框控件在客戶端的事件(下圖截取自Dreamweaver 8編輯器):
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=gb2312' />
<title>HTML控件的客戶端事件</title>
<script language='javascript'>
//下面的方法根據(jù)敲擊鍵盤的ASCII碼值來判斷是否敲擊了數(shù)字鍵
//數(shù)字鍵的ASCII碼值介于48到57之間,分別對應(yīng)數(shù)字0到9
//當(dāng)方法返回true的時候敲入的字符才能顯示
function judgeNumber(code)
{
//alert(code);
if(code>=48&<=57)
{
return true;
}
else
{
return false;
}
}
//英文字母A-Z的ASCII碼值65-90,a-z的ASCII碼值是97-122
//當(dāng)方法返回true的時候敲入的字符才能顯示
function judgeChar(code)
{
//alert(code);
if((code>=65&<=90)||(code>=97&<=122))
{
return true;
}
else
{
return false;
}
}
</script>
</head>
<body>
<form>
數(shù)字:<input type='text' name='userName' onkeypress='return judgeNumber(event.keyCode);' /><br/>
字母:<input type='text' name='password' onkeypress='return judgeChar(event.keyCode);' />
</form>
</body>
</html>
這個頁面的運行效果如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='TextBoxClient.aspx.cs' Inherits='TextBoxClient' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
<script language='javascript' type='text/javascript'>
//下面的方法根據(jù)敲擊鍵盤的ASCII碼值來判斷是否敲擊了數(shù)字鍵
//數(shù)字鍵的ASCII碼值介于48到57之間,分別對應(yīng)數(shù)字0到9
//當(dāng)方法返回true的時候敲入的字符才能顯示
function judgeNumber(code)
{
//alert(code);
if(code>=48&<=57)
{
return true;
}
else
{
return false;
}
}
//英文字母A-Z的ASCII碼值65-90,a-z的ASCII碼值是97-122
//當(dāng)方法返回true的時候敲入的字符才能顯示
function judgeChar(code)
{
//alert(code);
if((code>=65&<=90)||(code>=97&<=122))
{
return true;
}
else
{
return false;
}
}
</script>
</head>
<body>
<form id='form1' runat='server'>
<div>
數(shù)字:<asp:TextBox ID='TextBox1' runat='server' onkeypress='return judgeNumber(event.keyCode);'></asp:TextBox><br />
字母:<asp:TextBox ID='TextBox2' runat='server' onkeypress='return judgeChar(event.keyCode);'></asp:TextBox></div>
</form>
</body>
</html>
上面的程序在客戶端的最終效果和用普通HTML控件的效果一樣,只不過在Visual Studio 2005源視圖會得到如圖所示的提示:
FileUpload控件
FileUpload控件是一個很重要的控件,它被Web服務(wù)器最終解釋為形如“<input type=”file”…/>”這樣的普通HTML控件。
它有如下常見屬性:
屬性名 | 數(shù)據(jù)類型 | 說明 |
FileBytes | byte[] | 上傳的文件內(nèi)容的字節(jié)數(shù)組表示形式 |
FileContent | Stream | 上傳文件的數(shù)據(jù)流 |
FileName | string | 上傳文件在客戶端的名字 |
HasFile | bool | 指示是否上傳了文件 |
PostedFile | HttpPostedFile | 獲取文件基礎(chǔ)的HttpPostedFile對象 |
這個HttpPostedFile對象能幫我們做很多工作,它也有一些有用的常見屬性:
屬性名 | 數(shù)據(jù)類型 | 說明 |
ContentLength | int | 上傳的文件內(nèi)容的字節(jié)長度 |
ContentType | string | 上傳文件的MIME 內(nèi)容類型 |
FileName | string | 上傳文件的在客戶端的名字 |
InputStream | Stream | 指向上傳文件的Stream對象 |
FileUpload控件還有一個void SaveAs (string filename)的方法,這個方法用于將上傳的文件保存到服務(wù)器上。一般來說,使用FileUpload控件上傳文件一般有如下幾個步驟:
(1)利用HasFile屬性判斷是否上傳了文件。
(2)在服務(wù)器上指定一個物理路徑,并檢查這個物理路徑是否存在,如果不存在則先創(chuàng)建。
(3)指定上傳文件在服務(wù)器上的上傳路徑,利用SaveAs()保存上傳的文件。這一步還可以做一些其它檢查工作,比如檢查上傳的文件格式是否符合要求或文件內(nèi)容大小是否符合要求。
(4)將相對路徑或者URL地址保存起來,以便客戶訪問或者下載。
這里要著重強調(diào)的是:我們保存上傳的時候保存文件用的是物理路徑,但是要保存的、日后客戶端能訪問得到的卻是相對路徑或者URL地址。
下面是一個簡單的例子,這個頁面叫Upload.aspx,它的源視圖代碼如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='Upload.aspx.cs' Inherits='Upload' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>文件上傳的例子</title>
</head>
<body>
<form id='form1' runat='server'>
<div>
<asp:FileUpload ID='fileUpload' runat='server' />
<asp:Button ID='btnUpload' runat='server' OnClick='btnUpload_Click' Text='上傳' />
<asp:Literal ID='literal' runat='server'></asp:Literal></div>
</form>
</body>
</html>
后臺cs代碼如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class Upload : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnUpload_Click(object sender, EventArgs e)
{
//判斷是否上傳了文件
if (fileUpload.HasFile)
{
//指定上傳文件在服務(wù)器上的保存路徑
string savePath = Server.MapPath('~/upload/');
//檢查服務(wù)器上是否存在這個物理路徑,如果不存在則創(chuàng)建
if (!System.IO.Directory.Exists(savePath))
{
//需要注意的是,需要對這個物理路徑有足夠的權(quán)限,否則會報錯
//另外,這個路徑應(yīng)該是在網(wǎng)站之下,而將網(wǎng)站部署在C盤卻把上傳文件保存在D盤
System.IO.Directory.CreateDirectory(savePath);
}
savePath = savePath + '//' + fileUpload.FileName;
fileUpload.SaveAs(savePath);//保存文件
//不過需要注意的是,在客戶端訪問卻需要指定的是URL地址,而不是在服務(wù)器上的物理地址
literal.Text = string.Format('<a href='upload/{0}'>upload/{0}</a>', fileUpload.FileName);
}
}
}
以下是程序運行結(jié)果:
帶圖片預(yù)覽功能的FileUpload控件
通過上面的講述,我們知道一些web服務(wù)器控件在vs2005下沒有javascript客戶端事件的提示,不過只要我們確信這個事件對應(yīng)的HTML控件確實有,我們可以自行添加的,下面我們就來做一個讓FileUpload控件帶有圖片預(yù)覽功能的例子。
因為這里不涉及到上傳后如何保存,只是僅僅在用戶選擇了要上傳的文件時或者用戶將鼠標(biāo)移動到上傳控件上時,如果上傳的文件是圖片文件,我們就顯示這個圖片的預(yù)覽效果5分鐘,然后消失。以下是程序代碼(前臺代碼,保存代碼和上面的例子一樣,所以沒有寫后臺cs代碼):
<%@ Page Language='C#' %>
<!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>上傳圖片預(yù)覽實例</title>
<script type='text/javascript' language='javascript'>
//如果用戶選擇了圖片,則顯示圖片的預(yù)覽效果
function previewImage()
{
var x = document.getElementById('file');
if(!x || !x.value)//如果沒有選擇上傳文件
{
return;
}
var patn = //.jpg$|/.jpeg$|/.gif$/i;
if(patn.test(x.value))//如果上傳文件的后綴是.jpg或.jpeg或.gif
{
var y = document.getElementById('img');
if(y)
{
y.src = 'file://localhost/' + x.value;
y.style.display='block';
}
else
{
var img=document.createElement('img');
img.setAttribute('src','file://localhost/'+x.value);
img.setAttribute('width','120');
img.setAttribute('height','90');
img.setAttribute('id','img');
document.getElementById('form1').appendChild(img);
}
setTimeout('hidden()',5000); //5秒之后執(zhí)行隱藏圖片的javascript方法
}
else
{
alert('您選擇的似乎不是圖像文件。');
}
}
//隱藏照片
function hidden()
{
var y = document.getElementById('img');
if(y)
{
document.getElementById('img').style.display='none';
}
}
</script>
</head>
<body>
<form id='form1' runat='server'>
<div>
<asp:FileUpload ID='file' runat='server' onchange='previewImage()' onmouseover='previewImage()' />
<asp:Button ID='btnUpload' runat='server' Text='上傳' /></div>
</form>
</body>
</html>
說明一下,在這個頁面里form表單的id是form1,上傳控件的id是file,所以在客戶端用到了document.getElementById()這個方法來獲取相關(guān)的控件的屬性值,并且通過javascript腳本動態(tài)添加了一個<img id=”img”>的控件,然后我們操縱它的src屬性來決定顯示哪張圖片,利用它的style.display屬性來決定是否顯示。
以下預(yù)覽時的效果:
預(yù)覽5秒鐘之后,不再帶有預(yù)覽功能的效果:
注意:如果我們要上傳文件,需要給表單增加enctype='multipart/form-data'屬性,如果我們使用了FileUpload控件時,生成HTML代碼時表單會自動加上這個屬性。
Literal控件
Literal控件是一個類似于Label控件的控件,都是用來呈現(xiàn)文字的。前面我說過,雖然通過Response.Write()方法可以直接輸出文字,但是這樣輸出的文字有可能在<html></html>標(biāo)記之外,破壞了網(wǎng)頁的結(jié)構(gòu),使之不再符合XHTML標(biāo)準(zhǔn)。
對于靜態(tài)文字,我們可以直接在HTML代碼中書寫即可,而沒有必要使用Literal 控件或 Label 控件。但是在某些情況下我們卻希望在某個位置設(shè)置一些文字,那么我們就可以先在期望輸出文字的地方放置一個Literal控件,將來在程序代碼中根據(jù)程序邏輯動態(tài)設(shè)置Literal控件的Text屬性來控制要輸出的文字。
盡管在某種程度上,Literal 控件用法與 Label 控件用法類似,但是不同的是 Literal 控件不能用于將css樣式應(yīng)用于顯示的文本。
另外Literal 控件還有一個Mode屬性,它用來控制如何呈現(xiàn)Literal 控件中的內(nèi)容。這個屬性是一個枚舉,有三個枚舉值:
PassThrough:直接呈現(xiàn)Literal 控件中的內(nèi)容。
Encode:控件的內(nèi)容轉(zhuǎn)換為 HTML 編碼的字符串。
Transform:從控件的內(nèi)容中移除不受支持的標(biāo)記語言元素。如果 Literal 控件在支持 HTML 或 XHTML 的瀏覽器上呈現(xiàn),則不會修改該控件的內(nèi)容。
舉例說明,假如Literal的Text屬性為“<abc>http://blog.csdn.net/zhoufoxcn</abc>”,即如下代碼:
<table border='1' width='600' cellpadding='1' cellspacing='1'>
<tr><td>
Mode</td><td>
效果</td></tr>
<tr><td>
PassThrough</td><td>
<asp:Literal ID='Literal1' runat='server' Mode='PassThrough' Text='<abc>http://blog.csdn.net/zhoufoxcn</abc>'></asp:Literal></td></tr>
<tr><td>
Encode</td><td>
<asp:Literal ID='Literal2' runat='server' Mode='Encode' Text='<abc>http://blog.csdn.net/zhoufoxcn</abc>'></asp:Literal></td></tr>
<tr><td>
Transform</td><td>
<asp:Literal ID='Literal3' runat='server' Text='<abc>http://blog.csdn.net/zhoufoxcn</abc>'></asp:Literal></td></tr>
</table>
在瀏覽器的效果如下:
<table border='1' width='600' cellpadding='1' cellspacing='1'>
<tr><td>
Mode</td><td>
效果</td></tr>
<tr><td>
PassThrough</td><td>
<abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
<tr><td>
Encode</td><td>
<abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
<tr><td>
Transform</td><td>
<abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
</table>
在瀏覽器中查看的時候,PassThrough 和Transform模式的效果是一樣的,但是如果用智能設(shè)備查看的時候,PassThrough在客戶端的代碼仍然是<abc>http://blog.csdn.net/zhoufoxcn</abc>,而Transform模式在客戶端的代碼是http://blog.csdn.net/zhoufoxcn,要注意這個差別,Literal控件Mode屬性默認(rèn)是Transform模式。
Panel控件
Panel控件是一個容器控件,用來存儲一組容器控件,它常用來存放一組業(yè)務(wù)邏輯上相似的控件組。下面看一個例子,這個例子里會根據(jù)用戶選擇的性別動態(tài)決定對象配偶的名字,如果是男性則讓填寫妻子的名字,如果是女性則讓填寫丈夫的名字,源視圖代碼如下:
<%@ Page Language='C#' AutoEventWireup='true' CodeFile='PanelDemo.aspx.cs' Inherits='PanelDemo' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
</head>
<body>
<form id='form1' runat='server'>
<div>
性別:<asp:RadioButton ID='rbMale' runat='server' AutoPostBack='True' Checked='True' OnCheckedChanged='RadioButton_CheckedChanged' Text='男' GroupName='sex' />
<asp:RadioButton ID='rbFemale' runat='server' Text='女' AutoPostBack='True' GroupName='sex' OnCheckedChanged='RadioButton_CheckedChanged' /><br />
<asp:Panel ID='pMale' runat='server' Height='50px' Width='125px'>
妻子姓名:<asp:TextBox ID='TextBox1' runat='server'></asp:TextBox>
</asp:Panel>
</div>
<asp:Panel ID='pFemale' runat='server' Height='50px' Width='125px' Visible='False'>
丈夫姓名:<asp:TextBox ID='TextBox2' runat='server'></asp:TextBox>
</asp:Panel>
</form>
</body>
</html>
在這里我們用了兩個RadioButton控件,并且設(shè)置了它們的GroupName屬性都為“sex”,表示這兩個RadioButton屬于一個分組,它們之中只能有一個處于選中狀態(tài),另外我們還設(shè)置了這兩個RadioButton控件的AutoPostBack屬性都為“true”,表示當(dāng)它們的選擇狀態(tài)發(fā)生變化的時候,將會自動提交到服務(wù)器進(jìn)行處理,并且對于它們在服務(wù)器端的處理都都使用了同一個方法RadioButton_CheckedChanged,后臺代碼如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class PanelDemo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void RadioButton_CheckedChanged(object sender, EventArgs e)
{
//如果選擇的性別是“男”,則讓填寫妻子的姓名
if (rbMale.Checked)
{
pMale.Visible = true;
pFemale.Visible = false;
}
else//否則讓填寫丈夫的姓名
{
pMale.Visible = false;
pFemale.Visible = true;
}
}
}
程序的運行效果如下:
<div>
性別:<input id='rbMale' type='radio' name='sex' value='rbMale' checked='checked' /><label for='rbMale'>男</label>
<input id='rbFemale' type='radio' name='sex' value='rbFemale' onclick='javascript:setTimeout('__doPostBack(/'rbFemale/',/'/')', 0)' /><label for='rbFemale'>女</label><br />
<div id='pMale' style='height:50px;width:125px;'>
妻子姓名:<input name='TextBox1' type='text' id='TextBox1' />
</div>
</div>
<div>
上面的代碼是當(dāng)選擇“男”的時候生成的代碼,可見對于Panel控件在客戶端的代碼為一個<div>標(biāo)記。
PlaceHolder控件
PlaceHolder控件控件的作用和Panel控件的作用非常類似,也是用作容器控件,不過控件本身在客戶端不產(chǎn)生任何可見HTML標(biāo)記。
PlaceHolder控件有一個Controls屬性,這個屬性表示這個容器控件容納的控件的集合,Controls屬性是ControlCollection類的一個實例,這個類用Add()方法向集合中增加控件,用Remove()刪除控件,還有一個Count屬性表示這個集合中總共有多少個控件。
下面是一個PlaceHolder控件用法的例子,為了簡單起見,我沒有采用代碼和頁面分離的模式,代碼如下:
<%@ Page Language='C#' %>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<script runat='server'>
protected void Page_Load(object sender, EventArgs e)
{
Button btn = new Button();
btn.Text = '動態(tài)添加的控件';
btn.Click += new EventHandler(btn_Click);//給動態(tài)添加的Button的單擊事件增加服務(wù)器端方法
PlaceHolder1.Controls.Add(btn);
}
public void btn_Click(object sender, EventArgs e)
{
Literal l = new Literal();
l.Text = 'PlaceHolder1控件總共容納了' + PlaceHolder1.Controls.Count + '個控件';
PlaceHolder1.Controls.Add(l);
}
</script>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head runat='server'>
<title>無標(biāo)題頁</title>
</head>
<body>
<form id='form1' runat='server'>
<div>
<asp:PlaceHolder ID='PlaceHolder1' runat='server'></asp:PlaceHolder>
</div>
</form>
</body>
</html>
程序的運行結(jié)果:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' >
<head><title>
無標(biāo)題頁
</title></head>
<body>
<form name='form1' method='post' action='PlaceHolderDemo.aspx' id='form1'>
<div>
<input type='hidden' name='__VIEWSTATE' id='__VIEWSTATE' value='/wEPDwUKLTM2NTY5NjE1NWRkDxPVOfW9ygVx0MnTmn1nNCXGfWY=' />
</div>
<div>
<input type='submit' name='ctl02' value='動態(tài)添加的控件' />PlaceHolder1控件總共容納了1個控件
</div>
<div>
<input type='hidden' name='__EVENTVALIDATION' id='__EVENTVALIDATION' value='/wEWAgLhoKDXAwKfwImNCxlfxrs8MWJR7ujk/rFzZ1UfCrph' />
</div></form>
</body>
</html>
小結(jié):Panel和PlaceHolder作為控件的容器,在很多地方是相似的,不同的是PlaceHolder不會在客戶端產(chǎn)生任何可見的輸出,而Panel還可以設(shè)置背景圖片等。
Label和Literal控件常用來顯示文字(也可以成為文本的容器哦),在很多地方是相似的,不過不能設(shè)置Literal的客戶端css樣式,并且Literal對顯示的文本的控制能力更靈活一些,利用Mode屬性可以方便地顯示HTML代碼。
聯(lián)系客服