编程“方便面”之用户控件
2010-01-30 09:49 邢少 阅读(1835) 评论(12) 编辑 收藏 举报-
学习使用.net已经有数个年头,从使用.net进行cs开发,到现在做Web开发,一直都是想当然的写着、敲着。知道有一天,一个java开发者问我一个问题,我虽然将java语言已经还给母校了,但是还是可以读懂的。在我尝试解决它的问题的时候,发现那哥们无法理解我的想法,他是用eclipse开发java的,java组的一位资深的技术员过来后,对我的解决方法也是不感冒,问我为什么要那么写呢?为什么要那么爱用控件呢?而且不是很认同控件这种将特别功能需求进行封装的编程方式。但是作为一个已经.net语言思路的开发者,我还是很喜欢这些可爱的“控件”家伙的。鄙人感觉它们是体现高级编程语言特点的产物,是高效编程的必要组成。在项目中适度的”食用”,还是可以节省大量的代码开发量,并且可以实现页面功能之间的松耦合,使得代码更有条理。这一阵做了几个项目,在项目中对一些问题用“用户控件”做了适度的功能封装,感觉用起来很是方便,但是也感觉用些不足,贴出来互相学习,也希望和园子的朋友对用户控件的使用方式进行交流。
-
分页问题应该是web开发中的一个常见问题。Gridview控件虽然提供了分页的功能,但是严格的讲,它并不是真正的分页,只是“显示分页”罢了。我做的几个项目都是信息管理系统,数据量比较大,如果用gridview进行分页,在大访问量下实在是“惨”了点,所以就想用存储过程实现分页,每次只是取到本页的20条或者有限的数据。网络的上的存储过程很多,但是实际操作起来也很麻烦,所以就想把分页的功能封装起来,实现一个分页控制器的功能。
-
先说一下思路吧,我的想法是创建一个分页控制类来控制存储过程的读取,在控件的使用页面传递类似页码、表名称、等适当数量的条件参数,触发更新方法调用存储过程来刷新数据。编写设及的问题有3个:
-
1、分页控制类的封装,封装那些东西;
-
2、用户控件与宿主页面的数据交互;
-
3、分页存储过程;
-
首先是创建一个用户控件、控件起码要有样子,(”记录总共xx条 当前第x页 首页 上一页 下一页 末页 转到〔〕”之类的),简单搞定。至于后台的代码就是逻辑过程了。上一页的操作、下一页等的操作。根据传递的条件,相应的与分页控制类进行交互。
-
-
-
-
在页面中,我还放了两个隐藏字段来存储页面必要的两个字段,用来记录分页状态
-
-
<asp:HiddenField ID="hdfcurr" runat="server" Value="0" />
<asp:HiddenField ID="hdfcount" runat="server" Value="0" /> -
从用户控件与宿主页面的数据交互方面先说,delegate〔委托〕可以轻松实现,定义一个回调就可以实现。
-
public delegate void DelegateDataBind(DataTable dt);
private DelegateDataBind _dataBindEvent;
public DelegateDataBind dataBindEvent
{
get { return _dataBindEvent; }
set { _dataBindEvent = value; }
}
最后就是分页控制类了,这个应该对大家来说不是什么问题。我是在构造函数中定义参数,string[] 类型存储固定的几个参数。大家也可以用别的方式,反正是怎么方便怎么来。控制类定义 几个方法,上一页、下一页、首页、末页 、转到。还有一个就是初始化数据,代码直接贴出见下:
代码
/// <summary>
/// 分页控制类 作者:邢少
/// </summary>
public class DataPageView
{
private string _tableName;
private string _fldName;
private int _pageSize;
private string _fieldOrder;
private string _where;
private int _pageCount=1;
private int _currPage = 1;
private DataSet _ds;
private string _sort;
private string _strCondition;
private string _iD;
private int _rowCount;
#region 字段
/// <summary>
/// 数据总行数
/// </summary>
public int RowCount
{
get { return _rowCount; }
set { _rowCount = value; }
}
/// <summary>
/// 主键
/// </summary>
public string ID
{
get { return _iD; }
set { _iD = value; }
}
/// <summary>
/// 查询条件,不需where
/// </summary>
public string StrCondition
{
get { return _strCondition; }
set { _strCondition = value; }
}
/// <summary>
/// -排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记
/// </summary>
public string Sort
{
get { return _sort; }
set { _sort = value; }
}/// <summary>
/// 数据集
/// </summary>
public DataTable DataTableView
{
get
{
DataInitializtion();
return _ds.Tables[0];
}
}
/// <summary>
/// 分页显示的表名
/// </summary>
public string TableName
{
get { return _tableName; }
set { _tableName = value; }
}
/// <summary>
/// 要显示的字段列表
/// </summary>
public string FfldName
{
get { return _fldName; }
set { _fldName = value; }
}
/// <summary>
/// 每页显示的数据行
/// </summary>
public int PageSize
{
get { return _pageSize; }
set { _pageSize = value; }
}
/// <summary>
/// 以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC用于指定排序顺序
/// </summary>
public string FieldOrder
{
get { return _fieldOrder; }
set { _fieldOrder = value; }
}
/// <summary>
/// 查询条件
/// </summary>
public string Where
{
get { return _where; }
set { _where = value; }
}
/// <summary>
/// 总页数
/// </summary>
public int PageCount
{
get { return _pageCount; }
}
/// <summary>
/// 页数信息
/// </summary>
public string TablePageInfo
{
get
{
return string.Format("共 {0} 条记录, 当前第 {1}/{2} 页 每页{3}条记录", RowCount, _currPage <= _pageCount ? _currPage.ToString() : _pageCount.ToString(), _pageCount > 0 ? _pageCount.ToString() : "0", _pageSize);
}
}
public int CurrPgae
{
get { return _currPage; }
}
#endregion
public DataPageView(string[] list)
{
_iD = list[1];
_fldName = list[2];
_pageSize =20;
_strCondition = list[3];
_tableName = list[0];
_sort = list[5];
_fieldOrder = list[6];
_currPage = Convert.ToInt32(list[4]);
}
#region Methods
/// <summary>
/// 末页
/// </summary>
public void Last()
{
if (_pageCount == 0)
_currPage = 1;
else
_currPage = Convert.ToInt32(_pageCount);
}
/// <summary>
/// 首页
/// </summary>
public void Home()
{
_currPage = 1;
}
/// <summary>
/// 上页
/// </summary>
public void Up()
{
if (_currPage >1)
_currPage--;
}
/// <summary>
/// 下页
/// </summary>
public void Down()
{
if(_currPage<_pageCount)
_currPage++;
}
public void Goto(string currPage)
{
_currPage = Convert.ToInt32(currPage);
}
#endregion
private void DataInitializtion()
{
SqlParameter[] parameters = {
new SqlParameter("@psTblName", DbType.String),
new SqlParameter("@psStrGetFields", DbType.String),
new SqlParameter("@psPageSize", DbType.Int32),
new SqlParameter("@psPageIndex ", DbType.Int32),
new SqlParameter("@psOrderType", DbType.Byte),
new SqlParameter("@psStrWhere", DbType.String),
new SqlParameter("@psFieldName", DbType.String),
new SqlParameter("@rsPageCount", DbType.Int32),
new SqlParameter("@rsRecordCount", DbType.Int32)
};
parameters[0].Value = _tableName;
parameters[1].Value = _fldName;
parameters[2].Value = _pageSize;
parameters[3].Value = _currPage > 0 ? _currPage : 1;
parameters[4].Value = _sort;
parameters[5].Value = _strCondition;
parameters[6].Value = _fieldOrder;
parameters[7].Direction = ParameterDirection.Output; ;
parameters[8].Direction = ParameterDirection.Output; ;
_ds = HebHX.DBUtility.DbHelperSQL.RunProcedure("sp_general_pagination", parameters, "List");
_pageCount = Convert.ToInt32(parameters[7].Value);
_rowCount = Convert.ToInt32(parameters[8].Value);
if (_currPage > _pageCount) _currPage = _pageCount;
}
}
/// 分页控制类 作者:邢少
/// </summary>
public class DataPageView
{
private string _tableName;
private string _fldName;
private int _pageSize;
private string _fieldOrder;
private string _where;
private int _pageCount=1;
private int _currPage = 1;
private DataSet _ds;
private string _sort;
private string _strCondition;
private string _iD;
private int _rowCount;
#region 字段
/// <summary>
/// 数据总行数
/// </summary>
public int RowCount
{
get { return _rowCount; }
set { _rowCount = value; }
}
/// <summary>
/// 主键
/// </summary>
public string ID
{
get { return _iD; }
set { _iD = value; }
}
/// <summary>
/// 查询条件,不需where
/// </summary>
public string StrCondition
{
get { return _strCondition; }
set { _strCondition = value; }
}
/// <summary>
/// -排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记
/// </summary>
public string Sort
{
get { return _sort; }
set { _sort = value; }
}/// <summary>
/// 数据集
/// </summary>
public DataTable DataTableView
{
get
{
DataInitializtion();
return _ds.Tables[0];
}
}
/// <summary>
/// 分页显示的表名
/// </summary>
public string TableName
{
get { return _tableName; }
set { _tableName = value; }
}
/// <summary>
/// 要显示的字段列表
/// </summary>
public string FfldName
{
get { return _fldName; }
set { _fldName = value; }
}
/// <summary>
/// 每页显示的数据行
/// </summary>
public int PageSize
{
get { return _pageSize; }
set { _pageSize = value; }
}
/// <summary>
/// 以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC用于指定排序顺序
/// </summary>
public string FieldOrder
{
get { return _fieldOrder; }
set { _fieldOrder = value; }
}
/// <summary>
/// 查询条件
/// </summary>
public string Where
{
get { return _where; }
set { _where = value; }
}
/// <summary>
/// 总页数
/// </summary>
public int PageCount
{
get { return _pageCount; }
}
/// <summary>
/// 页数信息
/// </summary>
public string TablePageInfo
{
get
{
return string.Format("共 {0} 条记录, 当前第 {1}/{2} 页 每页{3}条记录", RowCount, _currPage <= _pageCount ? _currPage.ToString() : _pageCount.ToString(), _pageCount > 0 ? _pageCount.ToString() : "0", _pageSize);
}
}
public int CurrPgae
{
get { return _currPage; }
}
#endregion
public DataPageView(string[] list)
{
_iD = list[1];
_fldName = list[2];
_pageSize =20;
_strCondition = list[3];
_tableName = list[0];
_sort = list[5];
_fieldOrder = list[6];
_currPage = Convert.ToInt32(list[4]);
}
#region Methods
/// <summary>
/// 末页
/// </summary>
public void Last()
{
if (_pageCount == 0)
_currPage = 1;
else
_currPage = Convert.ToInt32(_pageCount);
}
/// <summary>
/// 首页
/// </summary>
public void Home()
{
_currPage = 1;
}
/// <summary>
/// 上页
/// </summary>
public void Up()
{
if (_currPage >1)
_currPage--;
}
/// <summary>
/// 下页
/// </summary>
public void Down()
{
if(_currPage<_pageCount)
_currPage++;
}
public void Goto(string currPage)
{
_currPage = Convert.ToInt32(currPage);
}
#endregion
private void DataInitializtion()
{
SqlParameter[] parameters = {
new SqlParameter("@psTblName", DbType.String),
new SqlParameter("@psStrGetFields", DbType.String),
new SqlParameter("@psPageSize", DbType.Int32),
new SqlParameter("@psPageIndex ", DbType.Int32),
new SqlParameter("@psOrderType", DbType.Byte),
new SqlParameter("@psStrWhere", DbType.String),
new SqlParameter("@psFieldName", DbType.String),
new SqlParameter("@rsPageCount", DbType.Int32),
new SqlParameter("@rsRecordCount", DbType.Int32)
};
parameters[0].Value = _tableName;
parameters[1].Value = _fldName;
parameters[2].Value = _pageSize;
parameters[3].Value = _currPage > 0 ? _currPage : 1;
parameters[4].Value = _sort;
parameters[5].Value = _strCondition;
parameters[6].Value = _fieldOrder;
parameters[7].Direction = ParameterDirection.Output; ;
parameters[8].Direction = ParameterDirection.Output; ;
_ds = HebHX.DBUtility.DbHelperSQL.RunProcedure("sp_general_pagination", parameters, "List");
_pageCount = Convert.ToInt32(parameters[7].Value);
_rowCount = Convert.ToInt32(parameters[8].Value);
if (_currPage > _pageCount) _currPage = _pageCount;
}
}
最后就是整一个存储过程,我这个也是从网络上copy的。随便网网吧,满地都是。
三个主要的问题都已经解决。最后看一下调用:
代码
if (ViewState["where"] == null) ViewState["where"] = "";
//绑定信息
DataPageView1.PageField = new string[] { "PTPosts", "PosID", "*", ViewState["where"].ToString(), "1", "0", "PosID" };
DataPageView1.dataBindEvent = delegate(DataTable dt) { rptPosts.DataSource = dt; rptPosts.DataBind(); };
//绑定信息
DataPageView1.PageField = new string[] { "PTPosts", "PosID", "*", ViewState["where"].ToString(), "1", "0", "PosID" };
DataPageView1.dataBindEvent = delegate(DataTable dt) { rptPosts.DataSource = dt; rptPosts.DataBind(); };
viewstate 存储的是页面的条件,主要是考虑比如在查询情况下的分页,回传的时候可以存储查询条件。
最下面就是对页面的数据控件的绑定。
现在一个分页控制用户控件就整理好了。贴出分页效果
应该还是很好用的,我在2个项目中都用到了它,很方便。现在贴出来与大家交流。我一直有想法想将该控件封装成为web控件,现在准备着手,为了想把它弄的更通用一些所以想准备的更充分些,好了就说这么多吧。
作者:邢少
关于作者:从业至今一直从事软件前沿的分析设计工作,对软件开发过程、项目管理有浓厚的兴趣。如有想法、建议,请多多赐教
本文版权归作者和博客园共有,欢迎转载,但未经作者同意请保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过 xingshaoxian@163.com 与我联系,非常感谢。