大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(十五)ASP.NET分页控件
2009-09-29 15:34 通用C#系统架构 阅读(5457) 评论(40) 编辑 收藏 举报 很多人都觉得,我只会C\S不懂B\S,平常还是B\S的工作做得比较多一些,以前也是以B\S开发为主,主要是工作上经常要做一些C\S的维护工作,所以我写出来的代码,基本上都是B\S,C\S上都是通用的,架构软件系统也都会往2个方面都考虑,尽量代码是兼容性比较好,毕竟辛苦写出来的代码,能有比较高的重复利用率生命力会更长一些。
由于应用的场景不一样,应用面向的对象不同,服务的行业也有所区别,对分页控件的要求也不一样,我是做管理类软件出身的,所以一直以内部管理类软件开发工作为主,一般是给公司的几十个人、几百个人用就可以了,经常在线操作的一般不会超过100个人,公司内部的网络带宽、服务器配置都非常好。例如我们现在的客户有2台,每台5万多元的IBM崭新服务器在跑我们的应用,每台有8G内存,1G的内部网络传输数据,所以我们写的程序就算性能差一些,也看不出来,在服务器上飞快的运行速度,所谓好马配好鞍吧,哈哈,当然我们的代码质量也是很高的运行性能也不差的,我的笔记本电脑是3G的内存。
我们对ASP.NET分页控件的要求:
1:跟数据库无关,我不能每个数据库都写个分页控件吧,最讨厌写存储过程的,碰到Oracle不是又要折腾了?
2:跟数据库访问层无关,我是获取出来的数据要分页,不是为了实现数据库访问功能,跟数据库访问无关。
3:需要排序、能查询过滤数据。
4:数据能删除、能编辑、最好还能导出之类的。
5:分页的代码调用简单明了,代码越少越好。
6:总共多少数据、总共几页、当前第几页、每页显示几条、跳转到第几条,等功能必须有。
7:最好能记录当前用户选了每页显示几条的记忆功能。
请看页面运行效果图:
代码是很早写的,质量不太高,因为运行很稳定,也没精力去修改完善,客户看到的是前台效果,并不在乎后台代码,也只能这么安慰自己了,有兴趣的朋友可以改进优化一下代码质量。
我们几万条记录的数据也进行过测试,运行也很快,客户的服务器这么好,内存这么大,浪费一点儿,笨一点儿,无所谓了,客户不会在于0.1秒的差别,开发的效率高、省事、省心、稳定、没有错误比那个更重要,何必跟自己过不去呢。
代码参考如下:
//------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2009 , Jirisoft , Ltd .
//------------------------------------------------------------
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;
namespace Water.Web
{
/// <remarks>
/// ControlsNavigator
/// 页面分页控制
///
/// 修改记录
///
/// 2006.01.03 版本:1.0 JiRiGaLa 整理代码。
///
/// 版本:1.0
///
/// <author>
/// <name>JiRiGaLa</name>
/// <date>2006.01.03</date>
/// </author>
/// </remarks>
public partial class ControlsNavigator : System.Web.UI.UserControl
{
public int PageCount = 0;
public int RowCount = 0;
private int currentPage = 0;
/// <summary>
/// 当前第几页
/// </summary>
public int CurrentPage
{
get
{
return this.currentPage;
}
set
{
this.currentPage = value;
}
}
int pageSize = 10;
/// <summary>
/// 每页显示几条数据
/// </summary>
public int PageSize
{
get
{
String perPage = this.cmbPerPage.SelectedValue;
if (perPage.Length > 0)
{
pageSize = int.Parse(perPage);
}
return pageSize;
}
set
{
pageSize = value;
this.cmbPerPage.SelectedValue = pageSize.ToString();
}
}
/// <summary>
/// 有新增功能的页数
/// </summary>
public int PageEditSize
{
get
{
String perPage = this.cmbPerPage.SelectedValue;
if (perPage.Length > 0)
{
pageSize = int.Parse(perPage) + 1;
}
return pageSize;
}
set
{
pageSize = value;
this.cmbPerPage.SelectedValue = pageSize.ToString();
}
}
public void Initialize()
{
if (this.cmbPerPage != null && this.cmbPerPage.Items.Count > 0)
{
this.cmbPerPage.SelectedIndex = 0;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
#region private void SetControlState(GridView gridView);
/// <summary>
/// 设置按钮的状态
/// </summary>
/// <param name="gridView">表格</param>
private void SetControlState(GridView gridView)
{
// 在中间的页面时
this.lbtnFirst.Enabled = true;
this.lbtnPrevious.Enabled = true;
this.lbtnNext.Enabled = true;
this.lbtnLast.Enabled = true;
// 第一页时候
if (gridView.PageIndex == 0)
{
this.lbtnFirst.Enabled = false;
this.lbtnPrevious.Enabled = false;
this.lbtnNext.Enabled = true;
this.lbtnLast.Enabled = true;
}
// 第后页时候
if (gridView.PageIndex == this.PageCount - 1)
{
this.lbtnFirst.Enabled = true;
this.lbtnPrevious.Enabled = true;
this.lbtnNext.Enabled = false;
this.lbtnLast.Enabled = false;
}
// 只有1页或者没内容时
if (this.PageCount < 2)
{
this.lbtnFirst.Enabled = false;
this.lbtnPrevious.Enabled = false;
this.lbtnNext.Enabled = false;
this.lbtnLast.Enabled = false;
}
// 当前页面的信息
this.CurrentPage = gridView.PageIndex;
this.lblCurrentPage.Text = this.PageCount > 0 ? (gridView.PageIndex + 1).ToString() : "0";
this.lblPageCount.Text = this.PageCount.ToString();
this.lblRowCount.Text = this.RowCount.ToString();
}
#endregion
#region public void BindData(GridView gridView, DataTable dataTable)
/// <summary>
/// 页面不存在添加功能
/// </summary>
/// <param name="gridView">当前Grid</param>
/// <param name="dataTable">数据源</param>
/// <param name="e">事件</param>
public void BindData(GridView gridView, DataTable dataTable)
{
PageChangeEventArgs e = new PageChangeEventArgs();
e.Action = "BindData";
this.BindData(gridView, dataTable, e);
}
#endregion
#region public void BindData(GridView gridView, DataTable dataTable, PageChangeEventArgs e)
/// <summary>
/// 页面不存在添加功能
/// </summary>
/// <param name="gridView">当前Grid</param>
/// <param name="dataTable">数据源</param>
/// <param name="e">事件</param>
public void BindData(GridView gridView, DataTable dataTable, PageChangeEventArgs e)
{
// 计算页面数
this.RowCount = dataTable.Rows.Count;
double pageCount = (double)RowCount / this.PageSize;
this.PageCount = (int)Math.Ceiling(pageCount);
if ((!Page.IsPostBack) || (e.Action.Equals("BindData")))
{
this.BindGoPage(PageCount);
}
gridView.DataSource = dataTable;
gridView.PageSize = this.PageSize;
switch (e.Action)
{
case "":
case "Search":
case "Sorting":
case "RowEditing":
case "RowCancelingEdit":
case "RowUpdating":
case "Delete":
case "Refresh":
break;
case "PageLoad":
case "BindData":
case "First":
case "PageSizeChanged":
gridView.PageIndex = 0;
gridView.EditIndex = -1;
this.BindGoPage(PageCount);
break;
case "Previous":
gridView.PageIndex--;
gridView.EditIndex = -1;
break;
case "Next":
gridView.PageIndex++;
gridView.EditIndex = -1;
break;
case "Last":
gridView.PageIndex = this.PageCount - 1;
gridView.EditIndex = -1;
break;
case "GoPage":
gridView.PageIndex = int.Parse(this.cmbGoPage.SelectedValue) - 1;
gridView.EditIndex = -1;
break;
default:
gridView.PageIndex = 0;
break;
}
// 页数不够了,进行调整
if (gridView.PageIndex >= this.PageCount)
{
gridView.PageIndex = this.PageCount == 0 ? 0 : this.PageCount - 1;
}
gridView.DataBind();
// 设置按钮的状态
this.SetControlState(gridView);
}
#endregion
#region public void BindData(GridView gridView, DataTable dataTable, PageChangeEventArgs e, int editIndex)
/// <summary>
/// 页面存在添加功能
/// </summary>
/// <param name="gridView">当前GridView</param>
/// <param name="dataTable">数据源</param>
/// <param name="e">当前事件</param>
/// <param name="editIndex">所要编辑的行数</param>
public void BindData(GridView gridView, DataTable dataTable, PageChangeEventArgs e, int editIndex)
{
// 计算页面数
this.RowCount = dataTable.Rows.Count;
double pageCount = (double)RowCount / (this.PageEditSize - 1);
this.PageCount = (int)Math.Ceiling(pageCount);
this.BindGoPage(PageCount);
gridView.DataSource = dataTable;
gridView.PageSize = this.PageEditSize;
gridView.EditIndex = editIndex;
switch (e.Action)
{
case "RowEditing":
{
gridView.PageSize = this.PageSize;
}
break;
case "RowCancelingEdit":
case "RowUpdating":
{
this.FormatTable(gridView, dataTable);
}
break;
case "Search":
case "Delete":
case "Refresh":
case "PageLoad":
case "First":
case "PageSizeChanged":
{
gridView.PageIndex = 0;
this.FormatTable(gridView, dataTable);
}
break;
case "Previous":
{
gridView.PageIndex--;
this.FormatTable(gridView, dataTable);
};
break;
case "Next":
{
gridView.PageIndex++;
this.FormatTable(gridView, dataTable);
};
break;
case "Last":
{
gridView.PageIndex = this.PageCount - 1;
this.FormatTable(gridView, dataTable);
}
break;
default:
gridView.PageIndex = 0;
break;
}
// 页数不够了,进行调整
if (gridView.PageIndex >= this.PageCount)
{
gridView.PageIndex = this.PageCount == 0 ? 0 : this.PageCount - 1;
}
gridView.DataBind();
// 获取按钮的状态
this.SetControlState(gridView);
}
#endregion
#region private void FormatTable(GridView gridView, DataTable dataTable)
/// <summary>
/// 格式化数据源
/// </summary>
/// <param name="gridView">当前GridView</param>
/// <param name="dataTable">数据源</param>
private void FormatTable(GridView gridView, DataTable dataTable)
{
int addEditIndex = 0;
for (int i = 1; i <= gridView.PageIndex; i++)
{
addEditIndex = i * (this.PageEditSize - 1);
dataTable.Rows.InsertAt(dataTable.NewRow(), addEditIndex);
}
if ((gridView.PageIndex + 1) * this.PageEditSize > dataTable.Rows.Count)
{
addEditIndex = dataTable.Rows.Count;
dataTable.Rows.InsertAt(dataTable.NewRow(), addEditIndex);
gridView.EditIndex = dataTable.Rows.Count - (gridView.PageIndex * gridView.PageSize) - 1;
}
else
{
addEditIndex = (gridView.PageIndex + 1) * this.PageEditSize - 1;
dataTable.Rows.InsertAt(dataTable.NewRow(), addEditIndex);
gridView.EditIndex = this.PageEditSize - 1;
}
dataTable.AcceptChanges();
}
#endregion
/// <summary>
/// 总共有几页的设置
/// </summary>
/// <param name="pageCount">页数</param>
private void BindGoPage(int pageCount)
{
this.cmbGoPage.Items.Clear();
for (int i = 1; i < pageCount+1; i++)
{
this.cmbGoPage.Items.Add(i.ToString());
}
}
protected void cmbGoPage_SelectedIndexChanged(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "GoPage"));
}
protected void lbtnFirst_Click(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "First"));
}
protected void lbtnPrevious_Click(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "Previous"));
}
protected void lbtnLast_Click(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "Last"));
}
protected void lbtnNext_Click(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "Next"));
}
protected void cmbPerPage_SelectedIndexChanged(object sender, EventArgs e)
{
OnPageChange(new PageChangeEventArgs(sender, "PageSizeChanged"));
}
public event PageChangeHandler PageChange;
protected virtual void OnPageChange(PageChangeEventArgs e)
{
if (PageChange != null)
{
PageChange(this, e);
}
}
}
public class PageChangeEventArgs : EventArgs
{
private String action = String.Empty;
public String Action
{
get
{
return this.action;
}
set
{
this.action = value;
}
}
public PageChangeEventArgs()
{
}
public PageChangeEventArgs(object sender, String paramAction)
{
this.Action = paramAction;
}
}
/// <summary>
/// 自定义翻页控件的页码委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void PageChangeHandler(object sender, PageChangeEventArgs e);
}
页面中的调用参考
//------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2009 , ESSE , Ltd .
//------------------------------------------------------------
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;
namespace Water.Web
{
using DotNet.Common.Model;
using DotNet.Common.Utilities;
using DotNet.Common.DbUtilities;
using DotNet.Common.Business;
using DotNet.Common.Service;
/// <remarks>
/// SendMessageByUser
/// 发送邮件
///
/// 2009.02.19 版本:1.0 JiRiGaLa 创建。
///
/// 版本:1.0
///
/// <author>
/// <name>JiRiGaLa</name>
/// <date>2009.02.19</date>
/// </author>
/// </remarks>
public partial class ContactSent : BasePage
{
// 功能分类代码
private String Function
{
set
{
this.txtFunction.Value = value;
}
get
{
return this.txtFunction.Value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
// 检查是否已登录
this.CheckIsLogin();
if (!Page.IsPostBack)
{
// 页面初次加载时的动作
this.DoPageLoad();
}
this.myNavigator.PageChange += new PageChangeHandler(this.myNavigator_PageChange);
}
#region private void DoPageLoad() 页面初次加载时的动作
/// <summary>
/// 页面初次加载时的动作
/// </summary>
private void DoPageLoad()
{
// 读取参数
//this.GetParamter();
try
{
this.DbHelper.Open();
// 从数据库读取参数
this.GetDataBaseParamter();
// 获取列表
this.GetList();
}
catch (Exception exception)
{
this.LogException(exception);
throw exception;
}
finally
{
this.DbHelper.Close();
}
// 设置按钮状态
}
#endregion
#region private void GetParamter() 读取参数
/// <summary>
/// 读取参数
/// </summary>
private void GetParamter()
{
if (Page.Request["Function"] != null)
{
this.txtFunction.Value = Page.Request["Function"].ToString();
}
if (Page.Request["Search"] != null)
{
this.txtSearch.Text = Page.Request["Search"].ToString();
}
}
#endregion
private void myNavigator_PageChange(object sender, PageChangeEventArgs e)
{
this.GetList(e);
}
#region private void GetList()
/// <summary>
/// 绑定信息
/// </summary>
private void GetList()
{
BaseContactDao contactDao = new BaseContactDao(this.DbHelper, this.UserInfo);
DataTable dataTable = contactDao.SearchSent(this.UserInfo.ID, String.Empty, false);
dataTable.DefaultView.Sort = BaseContactTable.FieldSortCode + " " + this.SortDire;
this.myNavigator.BindData(this.grdContact, dataTable);
this.DTContact = dataTable;
this.SetButtomState();
}
#endregion
#region private void GetList(PageChangeEventArgs e)
/// <summary>
/// 绑定信息
/// </summary>
/// <param name="e">事件</param>
private void GetList(PageChangeEventArgs e)
{
// 格式化数据
this.myNavigator.BindData(this.grdContact, this.DTContact, e);
if (e.Action == "PageSizeChanged")
{
try
{
this.DbHelper.Open();
// 保存分页参数
this.SaveDataBaseParamter();
}
catch (Exception myException)
{
this.LogException(myException);
throw myException;
}
finally
{
this.DbHelper.Close();
}
}
}
#endregion
#region private void SetButtomState() 设置按钮状态
/// <summary>
/// 设置按钮状态
/// </summary>
private void SetButtomState()
{
if (this.grdContact.Rows.Count == 0)
{
this.btnCheckAll.Enabled = false;
this.btnDelete.Enabled = false;
}
else
{
this.btnCheckAll.Enabled = true;
this.btnSearch.Enabled = true;
this.btnDelete.Enabled = true;
}
}
#endregion
#region private void Search() 查询
/// <summary>
/// 查询
/// </summary>
private void Search()
{
this.grdContact.PageIndex = 0;
try
{
this.DbHelper.Open();
this.DoSearch();
}
catch (Exception exception)
{
this.LogException(exception);
throw exception;
}
finally
{
this.DbHelper.Close();
}
// 是否显示提示信息
if ((this.ShowInformation) && (this.grdContact.Rows.Count == 0))
{
this.ClientScript.RegisterStartupScript(this.GetType(), "SearchFailure", "<script>alert('提示信息: 未找到查询内容.');</script>");
}
}
#endregion
#region private void GetDataBaseParamter() 从数据库读取参数
/// <summary>
/// 从数据库读取参数
/// </summary>
private void GetDataBaseParamter()
{
BaseParameterDao parameterDao = new BaseParameterDao(this.DbHelper, this.UserInfo);
String pageSize = parameterDao.GetParameter("User", this.UserInfo.ID, "Contact.PageSize");
if (pageSize.Length > 0)
{
this.myNavigator.PageSize = int.Parse(pageSize);
}
}
#endregion
#region private void SaveDataBaseParamter() 保存参数
/// <summary>
/// 保存参数
/// </summary>
private void SaveDataBaseParamter()
{
BaseParameterDao parameterDao = new BaseParameterDao(this.DbHelper, this.UserInfo);
parameterDao.SetParameter("User", this.UserInfo.ID, "Contact.PageSize", this.myNavigator.PageSize.ToString());
}
#endregion
#region private void DoSearch() 查询
/// <summary>
/// 进行查询
/// </summary>
private void DoSearch()
{
// 获取查询字符串
BaseContactDao contactDao = new BaseContactDao(this.DbHelper, this.UserInfo);
DataTable dataTable = contactDao.SearchSent(this.UserInfo.ID, this.txtSearch.Text, false);
dataTable.DefaultView.Sort = BaseContactDetailsTable.FieldCreateDate + " " + this.SortDire;
PageChangeEventArgs pageChangeEventArgs = new PageChangeEventArgs(this.btnSearch, "Search");
this.myNavigator.BindData(this.grdContact, dataTable, pageChangeEventArgs);
this.DTContact = dataTable;
this.SetButtomState();
}
#endregion
protected void btnSearch_Click(object sender, EventArgs e)
{
// 进行查询
this.Search();
}
protected void grdContact_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "color =this.style.backgroundColor;this.style.backgroundColor='LemonChiffon';");
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor = color;");
DataRowView dataRowView = (DataRowView)e.Row.DataItem;
String contactID = dataRowView[BaseContactTable.FieldID].ToString();
String title = dataRowView[BaseContactTable.FieldTitle].ToString();
title = HttpUtility.HtmlEncode(title);
HyperLink hyperLink = (HyperLink)e.Row.FindControl("Title");
// String newComment = dataRowView[BaseContactDetailsTable.FieldNewComment].ToString();
TableCell tableCell = e.Row.Cells[2];
//if (newComment.Equals(((int)MessageStateCode.New).ToString()))
//{
// tableCell.Text = "<img src='http://www.cnblogs.com/../Themes/Default/Images/" + this.Function + ".gif'; border='0'>";
//}
hyperLink.Text = title;
// hyperLink.NavigateUrl = "ContactRead.aspx?ID=" + contactID + "&ReturnURL=ContactSent.aspx";
if (!this.Function.Equals(MessageFunction.Warning.ToString()))
{
tableCell = e.Row.Cells[this.grdContact.Columns.Count - 1];
LinkButton linkButton = (LinkButton)tableCell.Controls[0];
if (linkButton != null)
{
String strScript = "return confirm('您确定要删除吗?');";
linkButton.Attributes.Add("onclick", strScript);
}
}
}
}
#region private void DeleteMark(String id) 删除事件
/// <summary>
/// 删除事件
/// </summary>
/// <param name="id">主键</param>
private void DeleteMark(String id)
{
int returnValue = 0;
try
{
this.DbHelper.Open();
BaseContactDetailsDao contactDetailsDao = new BaseContactDetailsDao(this.DbHelper, this.UserInfo);
returnValue = contactDetailsDao.SetDeleteMark(id);
this.GetList();
}
catch (Exception myException)
{
this.LogException(myException);
throw myException;
}
finally
{
this.DbHelper.Close();
}
// 是否显示提示信息
if (this.ShowInformation)
{
if (returnValue > 0)
{
this.ClientScript.RegisterStartupScript(this.GetType(), "DeleteSucceed", "<script>alert('提示信息:删除成功.');</script>");
}
else
{
this.ClientScript.RegisterStartupScript(this.GetType(), "DeleteFailure", "<script>alert('提示信息:删除失败.');</script>");
}
}
}
#endregion
protected void grdContact_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
String paramID = this.grdContact.DataKeys[e.RowIndex].Value.ToString();
// 删除事件
this.DeleteMark(paramID);
}
#region private int BathDelete() 批量删除
/// <summary>
/// 批量删除
/// </summary>
/// <returns>影响的行数</returns>
private int BathDelete()
{
int returnValue = 0;
string[] ids = this.GetSelecteIDs(this.grdContact);
try
{
this.DbHelper.Open();
BaseContactDetailsDao contactDetailsDao = new BaseContactDetailsDao(this.DbHelper, this.UserInfo);
returnValue = contactDetailsDao.SetDeleteMark(ids);
this.DoSearch();
}
catch (Exception myException)
{
this.LogException(myException);
throw myException;
}
finally
{
this.DbHelper.Close();
}
// 是否显示提示信息
if (this.ShowInformation)
{
if (returnValue > 0)
{
this.ClientScript.RegisterStartupScript(this.GetType(), "DeleteSucceed", "<script>alert('提示信息:删除成功。');</script>");
}
else
{
this.ClientScript.RegisterStartupScript(this.GetType(), "DeleteFailure", "<script>alert('提示信息:删除失败。');</script>");
}
}
return returnValue;
}
#endregion
protected void btnDelete_Click(object sender, EventArgs e)
{
// 批量删除
this.BathDelete();
}
protected void grdContact_Sorting(object sender, GridViewSortEventArgs e)
{
if (this.SortDire == "ASC")
{
this.SortDire = "DESC";
}
else
{
this.SortDire = "ASC";
}
this.SortExpression = e.SortExpression;
this.DTContact.DefaultView.Sort = this.SortExpression + " " + this.SortDire;
this.grdContact.EditIndex = -1;
PageChangeEventArgs pageChangeEventArgs = new PageChangeEventArgs(this.btnSearch, "Sorting");
this.myNavigator.BindData(this.grdContact, this.DTContact, pageChangeEventArgs);
this.SetButtomState();
}
private DataTable DTContact
{
get
{
return this.GetFromSession("_DTContact") as DataTable;
}
set
{
this.AddSession("_DTContact", value);
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
Response.Redirect("SendContactByUser.aspx");
}
}
}