在.net framework 2.0裡,使用VS2005,自訂GridView的Pager
,我的Windows Live Writer又在鬧脾氣了,怎麼發佈都沒有錯誤訊息,文章卻沒上來。只好手動貼了。
今天要介紹的,是怎麼在GridView裡面增加自訂的Pager。
請原諒我是個樣式白癡,我只能提供功能跟作法,樣式就請自行設計對應的css吧。
這邊舉的例子,是新增一個可以自行輸入頁碼的TextBox。有需要增加其他的Control,請照樣造句即可。
Download Source Code:GridViewPager.rar
Step1:
一樣新增一個類別庫叫做Joey,接著新增一個類別叫做JoeyGridView.cs並繼承GridView,
這邊我偷懶匯入了Microsoft.VisualBasic NameSpace,因為裡面有需要用到判斷數字,實在懶得自己寫function,就直接用VB內建的IsNumeric()了。
如果不想匯入VB的話,可以參考mis2000Lab大大的文章,[C#]以前在VB語法裡面用慣的 IsNumeric,在C#不見了??,主要還是使用Double.Tryparse()的function,
如果不是double,就自己選用適用的型別吧。
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.VisualBasic;
namespace Joey
{
public class JoeyGridView: GridView
{
}
}
Step2:
接著要覆寫的是OnRowCreated(),當e.row為Pager的時候,我們要插入自訂的Pager。
/// <summary>
/// 引發 <see cref="E:System.Web.UI.WebControls.GridView.RowCreated"/> 事件,並加入自訂的pager。
/// </summary>
/// <param name="e"><see cref="T:System.Web.UI.WebControls.GridViewRowEventArgs"/> 包含事件資料。</param>
protected override void OnRowCreated(GridViewRowEventArgs e)
{
base.OnRowCreated(e);
if (e.Row.RowType == DataControlRowType.Pager)
{ SettingPager(e.Row); }
}
#endregion
Step3:
再來就是精髓所在了,我們自訂Pager,要用TableRow的方式,插入原本的Pager裡。
並自訂新增Control的相關事件出來。
/// <summary>
/// Settings the pager.
/// </summary>
/// <param name="gridRow">The grid row.</param>
private void SettingPager(GridViewRow gridRow)
{
TableCell newCell = new TableCell();
TableRow tableRow = new TableRow();
newCell = CreatePagerTextBox();
tableRow = GetPagerTableRow(gridRow.Cells[0]);
tableRow.Cells.Add(newCell);
}
/// <summary>
/// Gets the pager's tablerow.
/// </summary>
/// <param name="gridRowCell">The grid row cell.</param>
/// <returns></returns>
private TableRow GetPagerTableRow(Control gridRowCell)
{
TableRow row = null;
while (gridRowCell.Controls.Count > 0)
{
row = gridRowCell as TableRow;
if (row != null)
{
break;
}
gridRowCell = gridRowCell.Controls[0];
}
return row;
}
/// <summary>
/// Creates text box in Grid pager .
/// </summary>
/// <returns></returns>
private TableCell CreatePagerTextBox()
{
TextBox sel = new TextBox();
sel.ID = "PageSizeSelector3";
sel.Text = Convert.ToString(this.PageIndex + 1);
sel.AutoPostBack = true;
sel.EnableViewState = true;
sel.Width = new Unit(30, UnitType.Pixel);
sel.TextChanged += new EventHandler(PageChangeSelectorByTextBox_Clicked);
TableCell newCell = new TableCell();
newCell.HorizontalAlign = HorizontalAlign.Right;
newCell.Controls.Add(sel);
return newCell;
}
#endregion
Step4:
最後是對Pager自訂事件的處理,這裡我們做三件事。
- 當輸入的值非數字時,維持原pageindex。
- 當輸入值>PageCount時,移至最後頁。
- 當輸入值比0小時,移至第一頁。
public event EventHandler PageIndexByTextChanged;
/// <summary>
/// Handles the Clicked event of the PageChangeSelectorByTextBox control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
/// <remarks>當輸入的值非數字時,維持原pageindex。
/// 當輸入值>PageCount時,移至最後頁。
/// 當輸入值比0小時,移至第一頁</remarks>
private void PageChangeSelectorByTextBox_Clicked(object sender, System.EventArgs e)
{
if (PageIndexByTextChanged != null)
{
TextBox ddl = (TextBox)sender;
string requestedPageSize = ddl.Text;
GridView grid = this;
try
{
if (Information.IsNumeric(requestedPageSize) & requestedPageSize.IndexOf(".") == -1)
{
int intrequestedPageSize = Convert.ToInt32(requestedPageSize);
if (intrequestedPageSize == 0)
{
ddl.Text = Convert.ToString(grid.PageIndex + 1);
}
else if (intrequestedPageSize <= grid.PageCount && intrequestedPageSize > 0)
{
grid.PageIndex = intrequestedPageSize - 1;
}
else if (intrequestedPageSize > grid.PageCount)
{
grid.PageIndex = grid.PageCount - 1;
ddl.Text = Convert.ToString(grid.PageCount);
}
if (PageIndexByTextChanged != null)
{
PageIndexByTextChanged(sender, e);
}
}
else
{
ddl.Text = Convert.ToString(grid.PageIndex + 1);
}
}
catch (Exception ex)
{
ddl.Text = Convert.ToString(grid.PageIndex + 1);
}
}
}
#endregion
}
Step5:
就這樣,大功告成。當然這樣的Code還是有美中不足的地方。
就是在TextChanged事件觸發的部分,還是需要額外自己寫Code去做Grid.DataBind()的動作。(跟原生的GridView.PageIndexChanging一樣)
如果有大大可以指導一下怎麼連那一段Code都省下來,小弟在這感激不盡!
建置一下類別庫,產生Joey.dll,加進網站參考裡,在頁面上拉一個JoeyGridView進來。
餵資料給GridView之後,還需額外撰寫事件重bind Grid的資料。(這邊樣式是套GridView的智慧標籤)
aspx:
<%@ Register Assembly="Joey" Namespace="Joey" TagPrefix="cc1" %>
<!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>
<cc1:JoeyGridView ID="JoeyGridView1" runat="server" OnPageIndexByTextChanged="JoeyGridView1_PageIndexByTextChanged" OnPageIndexChanging="JoeyGridView1_PageIndexChanging" AutoGenerateColumns="False" AllowPaging="True" CellPadding="4" ForeColor="#333333" GridLines="None" Width="100%">
<Columns>
<asp:BoundField DataField="Text" HeaderText="Text " />
<asp:BoundField DataField="Value" HeaderText="Value " />
<asp:BoundField DataField="CreatedDate" HeaderText="CreatedDate " />
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</cc1:JoeyGridView>
</div>
</form>
</body>
</html>
cs:資料我就隨便塞了,請原諒我的懶惰。
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 JoeyGridViewTest : System.Web.UI.Page
{
private DataTable _dtDt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
_dtDt.Columns.Add("Text");
_dtDt.Columns.Add("Value");
_dtDt.Columns.Add("CreatedDate");
_dtDt.Rows.Add(new string[] { "萬華區", "萬華", "2003/01/01" });
_dtDt.Rows.Add(new string[] { "中正區", "中正", "2003/01/01" });
_dtDt.Rows.Add(new string[] { "大同區", "大同", "2005/01/01" });
_dtDt.Rows.Add(new string[] { "台中市", "台中", "2005/01/01" });
_dtDt.Rows.Add(new string[] { "大甲鎮", "大甲", "2007/01/01" });
_dtDt.Rows.Add(new string[] { "台南市", "台南", "2007/01/01" });
_dtDt.Rows.Add(new string[] { "台北市", "北", "2007/01/01" });
_dtDt.Rows.Add(new string[] { "台中縣", "中", "2007/01/01" });
_dtDt.Rows.Add(new string[] { "台南縣", "南", "2010/01/01" });
_dtDt.Rows.Add(new string[] { "萬華區", "萬華", "2010/01/01" });
_dtDt.Rows.Add(new string[] { "中正區", "中正", "2010/01/01" });
if (!IsPostBack)
{
this.ViewState["source"] = _dtDt;
this.JoeyGridView1.DataSource = _dtDt;
this.JoeyGridView1.DataBind();
}
}
protected void JoeyGridView1_PageIndexByTextChanged(object sender, EventArgs e)
{
this.JoeyGridView1.DataSource = this.ViewState["source"];
string pageindex= ((TextBox)sender).Text;
this.JoeyGridView1.PageIndex = Convert.ToInt32(pageindex) - 1;
this.JoeyGridView1.DataBind();
}
protected void JoeyGridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.JoeyGridView1.DataSource = this.ViewState["source"];
this.JoeyGridView1.PageIndex = e.NewPageIndex;
this.JoeyGridView1.DataBind();
}
}
(忘記插上結果畫面…真的老了)
最後感謝mis2000lab大大的判斷C#自訂IsNumeric的文章。
我相信我這個自訂Pager的作法一定還有很大的改進空間,希望拋磚引玉一下,能有高手或其他大大們給予更多的建議。
blog 與課程更新內容,請前往新站位置:http://tdd.best/