日期:2012-06-01  浏览次数:20526 次

改善DataGrid的默認分頁使其更友好

        DataGrid是.net平台下開發Web應用程序最常用的控件,使用該控件可以幫助您專注與商務邏輯的開發,數據的顯示交給它來處理就好了,隻要簡單的設置一些相關的屬性,一張漂亮的表格就出來了,同時,它提供的模板列更大的提高了它的可編程性,使我們的設計更加靈活,想想都覺得這是一件興奮的事!然而,令人感覺美中不足的是,它的分頁功能實在是不怎麼樣,光禿禿的幾個數字掛在上面,既沒有統計信息又沒有跳頁功能,我想,這樣的用戶體驗太乏味了一點吧!於是我就想能不能改善它的分頁功能呢,使它具備上述功能!恩,現在想法有了,問題剩下如何實現?先讓我們想一下,DataGrid最終在客戶端表現為一個table,也就是說服務器將DataGrid解析為一段以<table>開始</table>結束的html代碼,然後將這段代碼發送到請求頁面的客戶端,請注意這個過程是先解析然後發送,既然過程是這樣的,那問題也就迎刃而解了,我們可以在解析後發送前這段時間為控件增加新的功能啊!接下來的問題是我要如何攔截到這段時間並讓整個過程停住去執行我寫的代碼,別急,先讓我們了解一下DataGrid的組成結構,DataGrid由行集和列集構成,它們分別在服務端表現為DataGrid.Items和DataGrid.Columns,DataGrid分頁區是一個DataGridItem,包含在整個Items集合中,每當DataGrid在創建一個Item時,都會引發一個ItemCreated事件,我們可以通過捕捉該事件來獲取"DataGrid分頁區"對象,並在該對象呈現至它包含的Page對象時,也就是發生PreRender事件時,編寫代碼為其加入新功能,如下所示:

private void dgProducts_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)

{

     if (e.Item.ItemType == ListItemType.Pager)

     {

           // 獲取DataGrid分頁區對象並為其指定PreRender事件的處理函數

           pagerItem = e.Item;

           pagerItem.PreRender += new System.EventHandler(this.pagerItem_PreRender);

     }

}

private void pagerItem_PreRender(object sender, EventArgs e)

{

     // 編寫事件處理代碼實現頁面統計信息以及跳頁功能

     .......

} 由於在執行上述事件時DataGrid已經經過解析生成了html,所以我們也隻能向其中添加html代碼來實現所需的功能。最終生成的新的分頁如下圖所示:

在實現跳頁功能時我使用JavaScript將用戶在文本框中輸入的值保存在一個Html隱藏字段裡,然後在服務端獲取該隱藏字段的值,並將DataGrid指定到該頁,我曾經試過用URL傳參數的方式並指定window.location為新的URL字符串,可是使用window.location會導致Page_Load()執行兩次。從而得不到想要的結果。我也考慮過使用ViewState,可那個文本框和按鈕是動態添加進去的Html標簽,事先沒有在服務端定義,又如何操控它們呢!於是這個念頭也就一閃而過了!到最後也隻有採用"隱藏字段"這種不怎麼高級但確實能解決的方法。以下是點"go"按鈕時執行的JavaScript函數:

function go(ctrl,max)

{

     // 驗証用戶輸入值是否符合要求

     if(ctrl.value >= 1 && ctrl.value <= max.innerText)

     {

           // 將輸入值保存到隱藏字段裡

           document.all.PageNum.value = ctrl.value;

     }

     else

     {

           alert('您輸入的頁碼必須是符合頁面要求的數字,最大值是:'+max.innerText);

           ctrl.value="";

           ctrl.focus();

           return false;

     }

}

全部代碼如下:

.Apsx.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using