GridView是ASP.NET界面開(kāi)發(fā)中的一個(gè)重要的控件,對(duì)GridView使用的熟練程度直接影響軟件開(kāi)發(fā)的進(jìn)度及功能的實(shí)現(xiàn)。(車延祿)
GridView的主要新特性:
1.與DataSource控件結(jié)合實(shí)現(xiàn)了顯示與數(shù)據(jù)操作的分離,大大減化了代碼的編寫量;
2.實(shí)現(xiàn)"雙向綁定",無(wú)需手動(dòng)檢索數(shù)據(jù)。
2.在列的類型上新增了CheckBoxField和ImageField兩個(gè)類型列;
3.對(duì)排序和分頁(yè)可以實(shí)現(xiàn)異步操作;
4.對(duì)其視圖狀態(tài)進(jìn)行優(yōu)化,使其運(yùn)行效率更高;
GridView與DataSource控件
要談GridView就必需要談DataSource,這兩個(gè)對(duì)象可稱得上是“最佳拍檔”。DataSource控件負(fù)責(zé)與數(shù)據(jù)源的交互,而GridView負(fù)責(zé)數(shù)據(jù)的顯示。它們之間通過(guò)“雙向綁定”聯(lián)系起來(lái),即DataSource控件將檢索出來(lái)的數(shù)據(jù)綁定到GridView中顯示,而GridView中修改和刪除的數(shù)據(jù)直接綁定到DataSource數(shù)據(jù)源去。這兩個(gè)過(guò)程由這兩個(gè)控件相互配合實(shí)現(xiàn)的,無(wú)需我們編寫代碼。如果我們只用GridView顯示數(shù)據(jù),而不用DataSource控件的話,那你只好編寫代碼實(shí)現(xiàn)DataSource要作的工作了。做為用過(guò)VS2003的用戶對(duì)這個(gè)工作并不陌生,但這種代碼實(shí)現(xiàn)不但工作量大,而且使用復(fù)雜,容量產(chǎn)生大量可讀性差的代碼,當(dāng)然也是初學(xué)者的最大障礙。好在VS2005為我們提供了DataSource控件,使我們不再如此痛苦地Coding了(當(dāng)然,如果有的情況下DataSource控件還無(wú)法完全替代Coding)。
所以在使用GridView控件的時(shí)候我們最好配合DataSource控件使用,不要再去折磨自己了。下面的案例不做特殊說(shuō)明均以GridView+DataSource控件實(shí)現(xiàn)。
一、GridView外觀設(shè)置:
1、總體外觀設(shè)置
ShowFooter:(bool)是否顯示頁(yè)腳
ShowHeader:(bool)是否顯示頁(yè)眉
GridLines:(enum)None-不顯示格線;Horizontal-顯示水平格線;Virtical-顯示豎直格線;Both-顯示水平和豎直格線
EmptyDataText:(string)如果數(shù)據(jù)源中內(nèi)容為NULL時(shí)在GridView中顯示的值
AlternatingRowStyle:交替項(xiàng)的樣式
EditRowStyle:編輯項(xiàng)的樣式
EmptyDataRowStyle:空數(shù)據(jù)項(xiàng)的樣式
FooterStyle:頁(yè)腳樣式
HeaderStyle:頁(yè)眉樣式
PagerStyle:分頁(yè)樣式
RowStyle:行樣式
SelectedRowStyle:選中項(xiàng)樣式
注:1、使用GridView的時(shí)候我們一般可以使用“自動(dòng)套用樣式”選中一個(gè)樣式,然后在此樣式的基礎(chǔ)上修改上面的屬性,從而制作出滿意外觀效果。
2、上面的樣式可以對(duì)GridView進(jìn)行總體的外觀設(shè)置,如果對(duì)某一列進(jìn)行設(shè)置的話那可要在GridView右上角“智能菜單中”點(diǎn)擊“編輯列”進(jìn)行設(shè)置。
如:
修改RowStyle-BackColor、RowStyle-Font、RowStyle-HorizontalAlign等屬性后
2、對(duì)綁定列進(jìn)行外觀設(shè)置
對(duì)上面的圖我們可以看出外觀方面有幾個(gè)問(wèn)題:
a.頁(yè)眉是英文的
b.所有的數(shù)據(jù)都是居中對(duì)齊
c.time列的數(shù)據(jù)中顯示了時(shí)分秒的數(shù)據(jù)
d.price列中應(yīng)加上"RMB"的符號(hào)
e.最好對(duì)價(jià)格列的數(shù)據(jù)以紅色字體顯示
上面的這些問(wèn)題我們可以通地單獨(dú)對(duì)列進(jìn)行格式設(shè)置來(lái)實(shí)現(xiàn)
點(diǎn)擊GridView右上角“智能菜單中”點(diǎn)擊“編輯列”,打開(kāi)"字段"窗口:
這個(gè)圖總體可以分作三大部分:可用字段,選中的字段,BoundField屬性
(1)“可用字段”:顯示了可供我們使用的列的類型
BoundField:綁定列,將數(shù)據(jù)庫(kù)中的數(shù)據(jù)以字符形式綁定顯示
CheckBoxField:復(fù)選框列,一般用來(lái)綁定數(shù)據(jù)庫(kù)中的Bit型數(shù),以復(fù)選框的形式顯示在GridView中
HyperLinkField:超鏈接列,可以用數(shù)據(jù)源中的數(shù)據(jù)作超鏈接文本也可以把所有超鏈接文本設(shè)為統(tǒng)一的文本
ImageField:圖片列,綁定數(shù)據(jù)源中的圖片路徑,并把圖片顯示出來(lái)
CommandField:命令列,常用的“選擇”,“刪除”,“編輯、更新、取消”
ButtonField:按鈕列,其它做用的按鈕
TemplateField:模板列,可以更靈活地自定義顯示格式
(2)“選定的字段”:從“可用字段”中添加進(jìn)來(lái)的,用來(lái)在GridView中顯示的列。其下方有個(gè)復(fù)選框“自動(dòng)生成字段”,如果選中了就會(huì)根據(jù)DataSource控件中檢索出來(lái)的數(shù)據(jù)自動(dòng)生成列,如果你要自己設(shè)置列的格式,請(qǐng)將此復(fù)選框清空。(車延祿)
(3)“BoundField屬性”:設(shè)置“每個(gè)可用字段”的屬性
我們可以根據(jù)自己的需要從“可用字段”中選擇列添加到“選中的字段中”,然后設(shè)置BoundField屬性。
在此我們先主要看BoundField列,其它類型的列后面再講解。
BoundField中的重要屬性:
ControlStyle:當(dāng)前列中控件的樣式
HeaderStyle:當(dāng)前列中頁(yè)眉的樣式
FooterStyle:當(dāng)前列中頁(yè)腳的樣式
ItemStyle:當(dāng)前列中數(shù)據(jù)行的樣式
ReadOnly:當(dāng)前列是否是只讀列,編輯的時(shí)候不顯示文本框
Sortexpression_r_r:排序表達(dá)式,這里只填數(shù)據(jù)源的列名
Visible:當(dāng)前列是否可見(jiàn)
HeaderText:頁(yè)眉文本
FooterText:頁(yè)腳文本
DataField:當(dāng)前列的數(shù)據(jù)行要顯示哪個(gè)字段的數(shù)據(jù),填寫字段名
DataFormatString:對(duì)顯示的數(shù)據(jù)進(jìn)行格式化顯示
上面的屬性太多,大家可以一時(shí)記下來(lái),其實(shí)也沒(méi)必要去記,只要見(jiàn)文知意就可以了。下面我們就用上面的內(nèi)容來(lái)解決外觀方法的問(wèn)題
第一步:清空“自動(dòng)生成字段”復(fù)選框
第二步:從“可用字段”中選擇“BoundField”添加到“選定的字段”中
第三步:點(diǎn)擊“選定的字段”中的每個(gè)字段,在“BoundField屬性”中設(shè)置
HeaderText--頁(yè)眉文本。如:“汽車名稱”
DataField--要在此列顯示數(shù)據(jù)的列名
第四步:設(shè)置"name"列的ItemStyle中的HorizontalAlign屬性為left,這樣只把name列的數(shù)據(jù)左對(duì)齊
第五步:設(shè)置"price"列的ItemStyle中的HorizontalAlign屬性為right,這樣只把price列的數(shù)據(jù)右對(duì)齊
第六步:在time列的DataFormatString屬性中設(shè)置為:"{0:d}"
第七步:在price列的DataFormatString屬性中設(shè)置為:"<fontcolor=red>RMB</font>{0}"
好了,大家可以看到上面的問(wèn)題我們都已解決了,效果還可以吧。
3、對(duì)數(shù)據(jù)行進(jìn)行外觀設(shè)計(jì)
對(duì)于列的設(shè)計(jì)我們可以通過(guò)可視化的界面進(jìn)行設(shè)計(jì),但是對(duì)于數(shù)據(jù)行的外觀設(shè)置就沒(méi)有那么簡(jiǎn)單了。由于我們不知道將來(lái)有多少行數(shù)據(jù)顯示,也不知道哪一條數(shù)據(jù)顯示在哪一行中,所以很難通過(guò)可視化的方式進(jìn)行設(shè)置。但這并不代表我們沒(méi)有辦法根據(jù)綁定的數(shù)據(jù)不同設(shè)置不同行的外觀。
要解決這個(gè)問(wèn)題我們先來(lái)研究一下GridView的綁定數(shù)據(jù)的過(guò)程:
當(dāng)我們?yōu)镚ridView設(shè)置了已配好數(shù)據(jù)源后,在運(yùn)行的時(shí)候,會(huì)把數(shù)據(jù)源中的數(shù)據(jù)綁定顯示出來(lái)。但由于GridView隱藏了自身在數(shù)據(jù)綁定過(guò)程中的構(gòu)建過(guò)程,所以使好多學(xué)JavaEE的同學(xué)感覺(jué)不如在<Table>標(biāo)記中嵌入for循環(huán)清晰,更使有的同學(xué)感到“GridView自動(dòng)生成的行讓人有點(diǎn)不太放心”。其實(shí),這是個(gè)思維導(dǎo)向的問(wèn)題,只要我們理解了在數(shù)據(jù)綁定時(shí)GridView界面的構(gòu)建過(guò)程,就不難發(fā)現(xiàn)GridView數(shù)據(jù)綁定的思路并不復(fù)雜。關(guān)鍵的是大家不要羈絆于JavaEE生成表格的思路中,要以一種開(kāi)放與求知的心態(tài)來(lái)研究GridView。
實(shí)際上在GridView在數(shù)據(jù)綁定的過(guò)程中是逐行實(shí)現(xiàn)的。是從GridView最上面的一行(頁(yè)眉或上分頁(yè)行)到最下面的一行(頁(yè)腳或下分頁(yè)行)逐行建造的。在建造每一行的過(guò)程中,又分為兩步:創(chuàng)建行和綁定行兩個(gè)步驟。下面分開(kāi)說(shuō):
創(chuàng)建行:就是根據(jù)數(shù)據(jù)源的結(jié)構(gòu)創(chuàng)建出n個(gè)單元格,并根據(jù)GridView的樣式和BoundFField屬性的樣式設(shè)置好每個(gè)單元格的樣式(背景色,前景色,字體等)。如果該行中有控件或靜態(tài)文本(設(shè)計(jì)時(shí)已寫死的文本,如頁(yè)眉文本)那在創(chuàng)建的時(shí)候也會(huì)直接創(chuàng)建控件或靜態(tài)文本。就像開(kāi)茶館一樣,把椅子、桌子、茶杯、開(kāi)水都備好了,就等客人來(lái)了(客人還沒(méi)來(lái)呢,因?yàn)檫@只是創(chuàng)建行,還沒(méi)有綁定行呢)。
綁定行:“創(chuàng)建行”執(zhí)行完后,再進(jìn)行“綁定行”。綁定行實(shí)際上就是把數(shù)據(jù)源中當(dāng)前行的數(shù)據(jù)逐一填寫到已創(chuàng)建好的行的相應(yīng)單元格里去。綁定行執(zhí)行完畢時(shí)才真正把一行數(shù)據(jù)建造完畢。這里就像把客人按排到相應(yīng)的已準(zhǔn)備好的坐位上喝茶。
在GridView綁定DataSource控件的時(shí)候?qū)嶋H上就是循環(huán)執(zhí)行“創(chuàng)建行”和“綁定行”的過(guò)程。如果我們能深入到每一行的“建造”過(guò)程中去,我們就可以根據(jù)綁定出來(lái)的數(shù)據(jù)控制當(dāng)前行的外觀樣式了。
非常幸運(yùn),GridView 為我們提供了兩個(gè)事件:RowCreated和RowDataBound事件
RowCreated事件:是每一行“創(chuàng)建行”完成時(shí)被觸發(fā)的事件。
RowDataBound事件:是每一行“綁定行”完成時(shí)被觸發(fā)的事件。
因此在綁定GridView顯示數(shù)據(jù)過(guò)程也就是循環(huán)觸發(fā)RowCreated事件和RowDataBound事件的過(guò)程。
下面的代碼驗(yàn)證了我上面的闡述:(車延祿)
protected void GridView1_RowCreated(objectsender, GridViewRowEventArgs e)
{
Response.Write(e.Row.RowType.ToString()+"Created=>");
}
protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
{
Response.Write(e.Row.RowType.ToString()+"DataBound=>");
}
執(zhí)行結(jié)果:
好了通過(guò)上面的講述,大家應(yīng)當(dāng)明白GridView的綁定過(guò)程了,也正有了上面的RowCreated和RowDataBound這兩個(gè)能被自動(dòng)觸發(fā)的事件,我們就可以像孫猴子鉆入鐵扇公主的肚子里那樣鉆入到GridView的創(chuàng)建過(guò)程中去,想怎么拆騰就怎么拆騰,完全由你了。
那下面我們就拆騰一下吧,對(duì)數(shù)據(jù)行實(shí)現(xiàn)下面的控制:
1.把“上市時(shí)間”列改為"yyyy年MM月dd日"的中文格式顯示
2.把價(jià)格高于50萬(wàn)元的高檔汽車用黃色前景和紅色字體顯示
3.計(jì)算當(dāng)前頁(yè)面中所有汽車的平均價(jià)格,并顯示在頁(yè)腳中
解決思路:
在GridView控件的RowDataBound事件中,取得每一行中相應(yīng)單元格中的數(shù)據(jù),把數(shù)據(jù)處理,重新寫回單元格中。
代碼如下:
//成員變量,用來(lái)累計(jì)當(dāng)前頁(yè)面中所有汽車的價(jià)格總和
private double _PriceSum;
protected void Page_Load(object sender, EventArgs e)
{
//顯示頁(yè)腳,以便在其中顯示平均價(jià)格
GridView1.ShowFooter =true;
}
//修改日期的顯示格式
private void ChangeDate(GridViewRowEventArgse)
{
if (e.Row.RowType ==DataControlRowType.DataRow)
{
if (e.Row.RowState == DataControlRowState.Normal ||e.Row.RowState ==DataControlRowState.Alternate)
{
//取出“上市時(shí)間”單元格中的日期文本
string dt = e.Row.Cells[3].Text;
if (dt != null && dt.Trim() !="")
{