|
譯序:此文章是今天在http://www.首頁發(fā)現(xiàn)的,詳細內(nèi)容地址是http://www./articles/displayarticle.aspx?id=511,作者Bipin Joshi。題目為Working with GridView without using Data Source Controls。 本文是根據(jù)原文的意思加自己的理解來翻譯的,這段時間自己翻譯過幾篇其它的文章,發(fā)現(xiàn)對于有些地方的翻譯真的就不能按照英文的愿意來,這也可能是文化差異的不同,所以我每篇翻譯都強調(diào)是“按照自己的理解”來翻譯,而且,是在保留作者原文的意思的基礎(chǔ)之上。 介紹: 大多數(shù)的文章和演練都是介紹如何用DataSource控件來配合GridView來工作的。當一個GridView被指定到一個DataSource控件的時,系統(tǒng)就會自動完成其分頁和排序的功能,而我們基本上是不用寫一行代碼的。然而,我們也會碰到直接把DataView和DataTable作為GridView綁定的對象的時候。幸運的是,GridView是可以用DataSource控件以外的方法來綁定數(shù)據(jù)的。但是需要開發(fā)人員敲額外的一些代碼,而你對ASP.NET1.X的DataGrid很熟悉的話,就會發(fā)現(xiàn)其過程是很象的。本文我們將來完成直接用DataView(或者DataTable)綁定到GridView如何操作的,并且在此基礎(chǔ)上實現(xiàn)分頁和編輯等功能。 示例:雇員列表 我們用Northwind數(shù)據(jù)庫的Employees表來做這個示例。在VS2005里新建一個站點,然后創(chuàng)建一個webform,拖拽一個GridView控件到此頁面上。用下圖的方法為GridView填加三個BoundFields和一個CommandField。
按照如下的表來設置各BoundField的屬性
進入到codebehind頁(也可能是code file),填加如下的代碼到Page_Load事件: protected void Page_Load(object sender, EventArgs e)![]() ![]() ![]() {![]() if(!IsPostBack)![]() ![]() ![]() {![]() BindGrid();![]() }![]() }![]() 然后,我們讓頁面在第一次顯示的時候調(diào)用BindGrid()方法。這個方法是我們自定義的方法,后面我們將介紹它的具體實現(xiàn)。這個方法實際上是讓一個DataView綁定到一個GridView上。而這個DataView里面是Employees表里的所有記錄。 實現(xiàn)分頁: 首先需要把GridView的AllowPaging屬性設置為True,這樣我們才可以實現(xiàn)分頁的功能。然后我們把PageSize屬性設置成3。這里有兩個和分頁有關(guān)的方法,它們分貝是: ·PageIndexChanging ·PageIndexChanged 第一個方法是在當前頁的這個屬性改變的時候被觸發(fā)的,第二個方法是這個屬性已經(jīng)被更改以后觸發(fā)的。而前一個方法你是可以在分頁的時候終止這個(分頁)操作的。 在GridView的PageIndexChanging事件里我們寫如下的代碼: protected void GridView1_PageIndexChanging![]() (object sender, GridViewPageEventArgs e)![]() ![]() ![]() {![]() GridView1.PageIndex = e.NewPageIndex;![]() BindGrid();![]() }![]() PageIndexChanging事件句柄里接收一個GridViewPageEventArgs類型的參數(shù)。這個參數(shù)通過一個叫做NewPageIndex的屬性來獲得用戶選擇的新頁的頁碼。我們再次調(diào)用BindGrid()方法把GridView的PageIndex的屬性設置成新頁碼。GridView就會把相應的內(nèi)容顯示出來。下面的截圖是GridView實現(xiàn)分頁以后的效果
實現(xiàn)排序: 實現(xiàn)排序的方法相對來說就要多做一些工作。首先,需要把GridView的AllowSorting屬性設置成True,然后,我們要給需要進行排列的BoundField列上設置SortExpression屬性.當你給相應的列設置好這個屬性以后你就會發(fā)現(xiàn)這個列的頭邊成了一個可點擊的Link button.單擊它會觸發(fā)如下的兩個事件: ·Sorting ·Sorted 和分頁方法一樣這兩個方法是有前后區(qū)別的。而Sorting事件也同樣允許你取消這個(排序)動作。 排序事件的句柄接收一個GridViewSortEventArgs類型的參數(shù)。GridViewSortEventArgs類有三個重要的屬性。SortExpression屬性提供先前你指定的排序表達式。SortDirection屬性描述是采用升序排序還是降序排序。著兒歌屬性在你用自己創(chuàng)建的列表里排序是沒什么用的,但是,當你用DataSource控件來為GridView做數(shù)據(jù)源的話它會為你自動指定排序的方法并且你可以通過通過這個屬性利用get或set的方法指定排序的方向。 既然我們不是用DataSource控件來作為數(shù)據(jù)源那么我們需要自己來寫排序的事件。我們用如下的方法來存儲一個ViewState變量,填加如下代碼到Sorting事件中。
protected void GridView1_Sorting(object sender, ![]() GridViewSortEventArgs e)![]() ![]() ![]() {![]() ViewState["sortexpression"] = e.SortExpression;![]() ![]() if (ViewState["sortdirection"] == null)![]() ![]() ![]() {![]() ViewState["sortdirection"] = "asc";![]() }![]() else![]() ![]() ![]() {![]() if (ViewState["sortdirection"].ToString() == "asc")![]() ![]() ![]() {![]() ViewState["sortdirection"] = "desc";![]() }![]() else![]() ![]() ![]() {![]() ViewState["sortdirection"] = "asc";![]() }![]() }![]() BindGrid();![]() }![]() ![]() 這里我們用一個sortexpression的ViewState變量來存儲SortExpression屬性。我們需要在BindGrid()方法里使用這個變量來讓排序在所有情況下都能正確進行。同樣我們也用一個叫做sortdirection的ViewState變量來存儲當前的排序方式。最后,我們調(diào)用DataBind()方法來把DataView里排序后的數(shù)據(jù)綁定給此數(shù)據(jù)網(wǎng)格。 下圖是實現(xiàn)排序以后的效果
實現(xiàn)編輯功能: 為了能在GridView里編輯記錄我們加入了一個CommandFields到GridView里,默認情況下你會看到它是一個title屬性為edit的link button.當我們單擊它以后觸發(fā)RowEditing事件并且編輯按鈕變成了“更新”和“取消”按鈕。單擊“更新”按鈕會出發(fā)RowUpdating事件,單擊“取消”按鈕會觸發(fā)RowCancelingEdit事件。我們需要寫入自己在RowUpdating事件里寫自己的更新代碼。 填加如下的代碼到RowEditing事件當中: protected void GridView1_RowEditing![]() (object sender, GridViewEditEventArgs e)![]() ![]() ![]() {![]() GridView1.EditIndex = e.NewEditIndex;![]() BindGrid();![]() }![]() RowEditing事件接收一個GridViewEditEventArgs類型的變量。類GridViewEditEventArgs有一個屬性叫做NewEditIndex來告訴我們用戶單擊的那一行的行號。然后根據(jù)這個值我們設置到GridView的EditIndex的值。這會使GridView進入到編輯模式,如下圖:
注意EmployeeID這一列是不能被編輯的因為這個列已經(jīng)被標志成ReadOnly. 然后我們填加如下代碼到RowCancelingEdit事件當中。 protected void GridView1_RowCancelingEdit![]() (object sender, GridViewCancelEditEventArgs e)![]() ![]() ![]() {![]() GridView1.EditIndex = -1;![]() BindGrid();![]() }![]() 這里我們把EditIndex的值設置成-1告訴系統(tǒng)我們現(xiàn)在要取消編輯操作。 最后,我們來看看RowUpdating事件的代碼:
protected void GridView1_RowUpdating![]() (object sender, GridViewUpdateEventArgs e)![]() ![]() ![]() {![]() int empid;![]() string fname, lname;![]() empid = int.Parse(GridView1.Rows[e.RowIndex].![]() Cells[0].Text);![]() fname = ((TextBox)GridView1.Rows[e.RowIndex].![]() Cells[1].Controls[0]).Text;![]() lname = ((TextBox)GridView1.Rows[e.RowIndex].![]() Cells[2].Controls[0]).Text;![]() ![]() SqlConnection cnn = new SqlConnection(@"data source=![]() .\sqlexpress;initial catalog=northwind;integrated ![]() security=true");![]() cnn.Open();![]() SqlCommand cmd = new SqlCommand("update employees set ![]() firstname=@fname,lastname=@lname where employeeid=@empid",![]() cnn);![]() cmd.Parameters.Add(new SqlParameter("@fname",fname));![]() cmd.Parameters.Add(new SqlParameter("@lname", lname));![]() cmd.Parameters.Add(new SqlParameter("@empid", empid));![]() cmd.ExecuteNonQuery();![]() cnn.Close();![]() ![]() GridView1.EditIndex = -1;![]() BindGrid();![]() }![]() ![]() 這里我們先得到在TextBox里我們輸入的值。RowUpdating方法接收一個GridViewUpdateEventArgs類型的變量,GridViewUpdateEventArgs類有一個叫做RowIndex的屬性告訴系統(tǒng)哪一行正在被更新。系統(tǒng)用GridView的Rows集合來獲得新輸入的值。注意系統(tǒng)是怎么利用Cells和Controls集合的。Cells集合包含了所有正在被編輯的這些列的對象。Controls集合存儲所把所有的空間都存儲成Control類型。因此系統(tǒng)需要把這些控件變成TextBox類型的對象。然后我們再用connection,command等數(shù)據(jù)庫對象執(zhí)行一個UPDATE操作。當更新操作完成后,系統(tǒng)會把GridView的EditIndex屬性設置成-1來完成更新操作。 BindGrid()方法: 前面我們提到過的這個方法,其代碼如下:
private void BindGrid()![]() ![]() ![]() {![]() DataSet ds = new DataSet();![]() SqlDataAdapter da = new SqlDataAdapter![]() ("select * from employees", @"data source=![]() .\sqlexpress;initial catalog=northwind;![]() integrated security=true");![]() da.Fill(ds,"employees");![]() DataView dv = ds.Tables[0].DefaultView;![]() ![]() if (ViewState["sortexpression"] != null)![]() ![]() ![]() {![]() dv.Sort = ViewState["sortexpression"].ToString() ![]() + " " + ViewState["sortdirection"].ToString();![]() }![]() ![]() GridView1.DataSource=dv;![]() GridView1.DataBind();![]() }![]() ![]() 通過這個方法,我們把Employees表里的數(shù)據(jù)填充到一個DataSet里。然后基于employees表創(chuàng)建一個DataView,再根據(jù)Sort屬性來對其排序。每一列需要排序的屬性都從ViewState變量里獲得sortexpression屬性。而當排序正在進行的時候也同樣是用到了這個變量,還記得我們在Sorting事件里設置的那兩個屬性嗎?就是它們。最后,我們把GridView的DataSource屬性在DataBind()方法里設置成這個DataView。 總結(jié) GridView是可以不用DataSource控件直接綁定到DataView或DataTable上的。我們同樣可以實現(xiàn)分頁,排序和編輯的功能。只不過,我們需要自己寫相應的代碼而已。 譯者后續(xù): 整體來說這個文章的難度不是很大,不過卻涉及到了最基本的ASP.NET的編程模型,目的是希望幫助更多的人來了解ASP.NET.讓大家更熟悉其結(jié)構(gòu)和運行模式,也可以讓更多的人順著此思路來更深一層次的掌握ASP.NET. 有意思的是有些地方翻譯起來很憋嘴,但是卻知道作者在說什么意思,所以干脆就直接拿自己的語言來表達作者的意思了。 另外最近由于項目的需要,正在研究從現(xiàn)有查詢系統(tǒng)的網(wǎng)站上抽取數(shù)據(jù)的方法,網(wǎng)上雖然能搜索到結(jié)果但是說的都很粗略,也正好也趕上項目有需要所以有機會研究這方面東西。為什么要提取,我們也知道現(xiàn)在很多治安管理系統(tǒng)都是很老的,基本上都是1999年那時候做出來的,并且每個系統(tǒng)都是不同公司做的,所以打算根據(jù)這些查詢系統(tǒng)自己寫一個提取查詢結(jié)果信息頁的方法,并且發(fā)布成Webservice來供其它類型的軟件或設備訪問。 |
|
|