自己做的数据绑定控件

控件|数据

很久都没有写一点东西了,最近一直在学习.net,前两天看到椰子林写的一篇《ASP.NET分页组件学与用》,于是自己就跟着做了一遍,一次成功,在此向他表示感谢,也向他那种共享的精神致敬!可是后来我发觉这个组件用起来有点麻烦,在Page_Load里面不但要得到记录集,还要写SQL语句分页,最后还要自己写代码将包含数据的<table></table>输出到客户端,于是我就想呀要是可以像DataGrid那样只是简单的绑定一下就可以用就好,分页,显示数据呀这些都交给组件去完成,正是这灵光一现,我就开始冲动了,没办法程序就是有这么大的魅力!结果,我昨天晚上失眠了,哎!冲动的惩罚呀!今天早上,我带着红肿的眼睛走进了机房,开始实现我昨天晚上梦见的那个东东,幸运的是--我实现了,呵呵,一个字爽!忘了告诉大家,我还是一个学生,做出来我很高兴了,技巧谈不上,高手们看了莫怪。下面我把基本的做法说一下!

如何做自定义控件,以及如何实现分页在这里我就不多说了,大家可以看一下椰子林写的相关文章,我要说说我的做法:

首先定义一个DataSource属性,如下:

private DataTable dt; //数据源

/// <summary>
/// 数据源
/// </summary>
public DataTable DataSource
{
get
{
return dt;
}
set
{
if (value == null)
throw new Exception("数据源不可为空");
else
dt = value;
}
}
该属性用于接受前端传进来的DataTable对象。我们可以在前端使用ADO.NET获得数据并将数据填充到一个DataTable中,再将此包含数据的DataTable赋于组件的DataSource属性,接下来的工作就是由组件向客户端输出包含数据的<table></table>标签了,怎么样简单吧!其实没有做多少改进,只是简单的扩展了一下,如下:

/// <summary>
/// 创建数据表
/// </summary>
/// <returns>表格的Html表示字符串</returns>
protected string CreateDataTable()
{
string table = null; //表格,显示了所有的字段和记录
string tableHead = null; // 表头用于显示字段名的<tr>
string tdHead = null; // 表头用于显示字段名的<td>包含在tableHead中
string tableBody = null; // 表主体用于显示记录的<tr>

// 为了实现分页定义min和max两个变量
// min代表从那一条记录开始显示
// max代表到那一条记录结束
// 如果当前是第2页每页显示10条记录的话,那么min的值就是10,max的值就是20
int min = 0;
int max = 0;

// for循环用于产生表头,即字段名
for (int i = 0; i < this.dt.Columns.Count; i++)
{
tdHead = tdHead + "<td>" + this.dt.Columns[i].ColumnName + "</td>";
}

// 判断当前页是否最后一页
if (this.currentpage == this.PageCount)
{
min = (this.currentpage - 1) * this.count;
max = this.dt.Rows.Count;
}
else
{
min = (this.currentpage - 1) * this.count;
max = this.currentpage * this.count;
}

// for循环用于产生表主体,即提取记录
for (int j = min; j < max; j++)
{
tableBody = tableBody + "<tr bgcolor='#FFFFFF'>";

for (int k = 0; k < this.dt.Columns.Count; k++)
{
tableBody = tableBody + "<td>" + this.dt.Rows[j][k].ToString() + "</td>";
}

tableBody = tableBody + "</tr>";
}

tableHead = "<tr bgcolor='#FFFFFF'>" + tdHead + "</tr>";

table = "<table border='0' cellpadding='0' cellspacing='1' width='100%' height='100%' bgcolor='#000000' style='font-size:9pt'>" + tableHead + tableBody + "</table>";

return table;
}

这样就得到了包含数据的表格的Html字符串,跟着就是做分页部分,最后重写Render(HtmlTextWriter output)方法将整个组件输出到客户端!这里我不一一详述步骤,我把代码帖出来,有兴趣的可以将代码拷贝到本机上运行一下!

组件源代码如下:(调试通过)

public class MyDataGrid : System.Web.UI.WebControls.WebControl
{
private int currentpage; //当前页
private int count; //每页显示的记录条数
private int navigcount; //导航连接的个数
private DataTable dt; //数据源

private const string SCRIPTSTRING = "<script language='javascript'>\n" +
" function go(ctrl,max)\n" +
"{\n" +
"if(ctrl.value >= 1 && ctrl.value <= max)\n" +
"{\n" +
"var url;\n" +
"var index;\n" +
"url = location.href;\n" +
"index = url.indexOf('?');\n" +
"if(index == -1)\n" +
"{\n" +
"}\n" +
"else\n" +
"{\n" +
"url = url.substring(0,index);\n" +
"}\n" +
"location.href = url + '?CurrentPage=' + ctrl.value;\n" +
"}\n" +
"else\n" +
"{\n" +
"alert('您输入的页码必须是符合页面要求的数字,最大值是:' + max);\n" +
"return false;\n" +
"}\n" +
"}\n" +
"</script>\n";

/// <summary>
/// 当前页
/// </summary>
public int CurrentPage
{
get
{
return currentpage;
}
set
{
if (value <= 0)
currentpage = 1;
else
currentpage = value;
}
}

/// <summary>
/// 每页显示的记录条数
/// </summary>
public int Count
{
get
{
return count;
}
set
{
if (value <= 0)
count = 10;
else
count = value;
}
}

/// <summary>
/// 导航连接的个数
/// </summary>
public int NavigCount
{
get
{
return navigcount;
}
set
{
if (value <= 0)
navigcount = 10;
else
navigcount = value;
}
}

/// <summary>
/// 总页数
/// </summary>
public int PageCount
{
get
{
if (this.dt.Rows.Count % count > 0)
return ((int)this.dt.Rows.Count / count) + 1;
else
return ((int)this.dt.Rows.Count / count);
}
}

/// <summary>
/// 数据源
/// </summary>
public DataTable DataSource
{
get
{
return dt;
}
set
{
if (value == null)
throw new Exception("数据源不可为空");
else
dt = value;
}
}

protected override void Render(HtmlTextWriter output)
{
string Table = CreateDataTable();
string PageControl = CreatePageControl();

string Result = string.Format("<table border='0' cellpadding='0' cellspacing='1' width='724' height='93' bgcolor='#000000' style='font-size: 9pt'>\n" +
"<tr bgcolor='#FFFFFF'>\n" + "<td width='724' height='68' valign='top'>{0}</td>\n" + "</tr>\n" +
"<tr bgcolor='#FFFFFF'>\n" + "<td width='724' height='25' valign='top'>{1}</td>\n" + "</tr>\n" + "</table>\n",Table.ToString(),PageControl.ToString());

output.Write(Result.ToString());
}

/// <summary>
/// 创建数据表
/// </summary>
/// <returns>表格的Html表示字符串</returns>
protected string CreateDataTable()
{
string table = null; //表格,显示了所有的字段和记录
string tableHead = null; // 表头用于显示字段名的<tr>
string tdHead = null; // 表头用于显示字段名的<td>包含在tableHead中
string tableBody = null; // 表主体用于显示记录的<tr>

// 为了实现分页定义min和max两个变量
// min代表从那一条记录开始显示
// max代表到那一条记录结束
// 如果当前是第2页每页显示10条记录的话,那么min的值就是10,max的值就是20
int min = 0;
int max = 0;

// for循环用于产生表头,即字段名
for (int i = 0; i < this.dt.Columns.Count; i++)
{
tdHead = tdHead + "<td>" + this.dt.Columns[i].ColumnName + "</td>";
}

// 判断当前页是否最后一页
if (this.currentpage == this.PageCount)
{
min = (this.currentpage - 1) * this.count;
max = this.dt.Rows.Count;
}
else
{
min = (this.currentpage - 1) * this.count;
max = this.currentpage * this.count;
}

// for循环用于产生表主体,即提取记录
for (int j = min; j < max; j++)
{
tableBody = tableBody + "<tr bgcolor='#FFFFFF'>";

for (int k = 0; k < this.dt.Columns.Count; k++)
{
tableBody = tableBody + "<td>" + this.dt.Rows[j][k].ToString() + "</td>";
}

tableBody = tableBody + "</tr>";
}

tableHead = "<tr bgcolor='#FFFFFF'>" + tdHead + "</tr>";

table = "<table border='0' cellpadding='0' cellspacing='1' width='100%' height='100%' bgcolor='#000000' style='font-size:9pt'>" + tableHead + tableBody + "</table>";

return table;
}

/// <summary>
/// 创建分页控件
/// </summary>
/// <returns>返回分页控件的Html表示字符串</returns>
protected string CreatePageControl()
{
string leftInfo = string.Format("页:{0}/{1}"+"  "+"每页{2}条"+"  "+"共{3}条",
this.CurrentPage.ToString(),this.PageCount.ToString(),this.Count.ToString(),this.dt.Rows.Count.ToString());

int min = 0;
int max = 0;

if (this.CurrentPage > this.PageCount)
{
this.CurrentPage = this.PageCount;
}

if (this.CurrentPage % this.Count == 0)
{
min = this.CurrentPage + 1;
max = this.CurrentPage + this.Count;
}
else if (this.CurrentPage % this.Count == 1&& this.CurrentPage > this.Count)
{
min = (((int)this.CurrentPage / this.Count) - 1) * this.Count + 1;
max = this.CurrentPage - 1;
}
else
{
min = ((int)this.CurrentPage / this.Count) * this.Count + 1;
max = (((int)this.CurrentPage / this.Count) + 1) * this.Count;
}

string numberStr = " ";
string url = this.Context.Request.Url.ToString();

if (url.IndexOf("?") == -1)
{
}
else
{
url = url.Substring(0,url.IndexOf("?"));
}

for (int i = min; i <= max; i++)
{
if (i <= this.PageCount)
{
if (i == this.CurrentPage)
{
numberStr = numberStr + "<a href=" + url + "?CurrentPage=" + i.ToString() + ">" + "<I style='color:red'>" + i.ToString() + "</I>" +"</a>" + "\n";
}
else
{
numberStr = numberStr + "<a href=" + url + "?CurrentPage=" + i.ToString() + ">" + i.ToString() +"</a>" + "\n";
}
}
}

string first,prev,next,last;
first = url + "?CurrentPage=" + 1;

if (this.CurrentPage == 1)
{
prev = url + "?CurrentPage=1";
}
else
{
prev = url + "?CurrentPage=" + (this.CurrentPage - 1).ToString();
}

if (this.CurrentPage == this.PageCount)
{
next = url + "?CurrentPage="+ this.PageCount;
}
else
{
next = url + "?CurrentPage=" + (this.CurrentPage + 1).ToString();
}

last = url + "?CurrentPage=" + this.PageCount;

string centerInfo = string.Format("<font face='Webdings' style='font-size:14px'><a href={0}>7</a><a href={1}>3</a></font>{2}<font face='Webdings' style='font-size:14px'><a href={3}>4</a><a href={4}>8</a></font>",first,prev,numberStr,next,last);

string result = string.Format("<table border='0' cellpadding='0' cellspacing='0' width='100%' style='font-size:9pt'>\n" +
"<tr><td width='25%' align='left'>{0}</td>\n" +
"<td width='61%' align='right'>{1}</td>" +
"<td width='14%' align='right'><input type='text' name='T1' size='4' style='border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;'> \n <input type='button' name='B1' size='6' value=go style='border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;' ></td>\n" +
"</tr></table>",leftInfo,centerInfo,this.PageCount);

return result;
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
if(!Page.IsClientScriptBlockRegistered("WEREW-332DFAF-FDAFDSFDSAFD"))
{
Page.RegisterClientScriptBlock("WEREW-332DFAF-FDAFDSFDSAFD",SCRIPTSTRING);
}
}
}

测试工程代码:

public class TestMyDataGrid : System.Web.UI.Page
{
protected myControlLibrary.MyDataGrid MyDataGrid1;

private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
int currentpage;
if (this.Request.Params["CurrentPage"] == null)
{
currentpage = 1;
}
else
{
currentpage = Convert.ToInt32(this.Request.Params["CurrentPage"].ToString());
}

this.MyDataGrid1.CurrentPage = currentpage;
this.MyDataGrid1.Count = 10;
this.MyDataGrid1.NavigCount = 10;

SqlConnection conn = new SqlConnection("server=localhost; database=NorthWind; uid=sa");
SqlCommand cmd = new SqlCommand("select * from [Order Details]",conn);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();

conn.Open();
da.Fill(ds,"table");
conn.Close();

this.MyDataGrid1.DataSource = ds.Tables["table"];
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}

页面版排的不好,只好劳动一下你,呵呵!

时间: 2024-08-31 13:01:36

自己做的数据绑定控件的相关文章

ASP.NET 2.0 和数据绑定控件:新的角度,新的做法

asp.net|控件|数据 适用于:Microsoft ASP.NET 1.xMicrosoft ASP.NET 2.0 摘要:了解 ASP.NET 2.0 中的用于生成自定义数据绑定控件的工具是如何演变的.   本页内容 为什么需要新的数据源模型  ASP.NET 2.0 中的数据绑定控件  分析要点  数据绑定机制   列表控件  HeadlineList 示例控件  管理自定义集合  关于复合控件的一点讨论  小结 为什么需要新的数据源模型数据绑定是开发人员在 ASP.NET 1.x 中发

浅谈ASP.NET常用数据绑定控件优劣总结_实用技巧

本文的初衷在于对Asp.net常用数据绑定控件进行一个概览性的总结,主要分析各种数据绑定控件各自的优缺点,以便在实际的开发中选用合适的控件进行数据绑定,以提高开发效率. 因为这些数据绑定控件大部分都已经封装的很好了,稍微有一些基础的朋友都可以很容易的上手使用,所以本文不涉及具体控件的使用,只在于分析各自的优劣点,但是在下一篇文章里,我会主要讲一下ListBox.GridView.Repeater这三个数据绑定控件的"高效分页",ListBox和GridView内置的有分页,但是其效率太

数据绑定控件:DataSource属性

数据绑定控件,都有DataSource属性,用于指定数据源.通常情况下,也是比较常用的就是数据源是数据表(DataTable),其实DataSource的范围很广,我们可以在深入研究的同时,改善我们的程序. 有的时候,你在编程进入一定阶段,进一步提升很困难的境况之下,不妨回过头来看看基础的东西,或许你会有新的受益,或许能够真正的体会到孔夫子所谓的"温故而知新"的真正内涵. 常用的数据绑定控件有:Repeater.DataList.GridView.DetailsView等,在这里我拿R

非常ASP.NET: 您将需要用到的独有数据绑定控件

随 Visual Studio 2008 一同发布的 ASP.NET 3.5 引入了新的数据绑定控件-ListView. 我知道您正在想什么:为什么 ASP.NET 里还需要另一个数据绑定控件呢?毕竟,当显示数据收集时,我们 已经有超过 10 个控件可供选择,其中包括逐渐不再使用的 DataGrid.新的和改进的 GridView.非常可 靠和简单的 Repeater.独特和灵活的 DataList.方便的 FormView 及其稍显冗余的同行 DetailsView. 当然,还有一维列表控件

asp.net夜话之八:数据绑定控件(一)

通过前面的例子我们看到每次我们要显示数据的时候都要通过一个循环来显示满足条件的数据,这是一个比较麻烦的过程,为此微软定义了一系列的控件专门用于显示数据的格式,通过这些控件可以以可视化的方式查看绑定数据之后的效果.这些控件称之为数据绑定控件.在asp.net中所有的数据库绑定控件都是从BaseDataBoundControl这个抽象类派生的,这个抽象类定义了几个重要属性和一个重要方法: DataSource属性:指定数据绑定控件的数据来源,显示的时候程序将会从这个数据源中获取数据并显示. Data

绑定Enum到ASP.NET数据绑定控件的完美解决方案

本文向读者介绍NBear中实现的DropDownListField字段绑定控件和EnumDescriptionAttribute特性.结合使用这两个组件,就可以最简单.易用和可扩展地完美解决绑定Enum到ASP.NET数据绑定控件的问题.[05/26修订]--增加支持第三方枚举描述,支持二进制与过的枚举值. 从DropDownListField的名称,大家一定猜到了,是的,DropDownListField控件和ASP.NET内置的BoundField,CheckBoxField等一样,可以直接

activex-使用MFC做的ActiveX控件

问题描述 使用MFC做的ActiveX控件 为什么用IE浏览器测试ActiveX控件时,关闭浏览器时,它的进程还在运行. 解决方案 那进程是什么? ActiveX的宿主进程不是IE?

asp.net学习之 数据绑定控件--表格绑定控件

原文:asp.net学习之 数据绑定控件--表格绑定控件     数据绑定 Web 服务器控件是指可绑定到数据源控件,以实现在 Web 应用程序中轻松显示和修改数据的控件.数据绑定 Web 服务器控件是将其他 ASP.NET Web 控件(例如 Label 和 TextBox 控件)组合到单个布局中的复合控件.     例如,诸如 DetailsView 控件等数据绑定控件可绑定到一个结果集,例如,包含每个雇员的姓名.地址.职务等信息的雇员表.在 DetailsView 控件中,可以将 Labe

asp.net学习之数据绑定控件、数据源控件概述

原文:asp.net学习之数据绑定控件.数据源控件概述 1.asp.net数据绑定控件分为三大类,每个类分别进行详细:      ● 列表式数据绑定控件: 列表式数据绑定控件常用来在一个表格内的一个字段进行绑定.显示一个字段下所有数据的信息.           它包括以下几个控件:BulletedList.CheckboxList.DropDownList.ListBox.RadioButtonList           具体的参照以下文章:  http://www.cnblogs.com/