asp.net自定义控件
这段时间一直想自己做个控件玩玩,原本准备做一个像repeater差不多 当然最初的设想用起来要比repeater方便,包括在CSS和一些JS,jquery的使用上面
和repeater进行对比,但是做出来后发现代码绕了好多,控件直接读取数据库的话还要封装好读取数据库的代码,如果不封装在后期的使用过程中会对整个项目都必
定会有很多的约束。虽然这是个偏离原来目的的控件,但是对于初学者来说 应该还有参考价值。
下面贴出控件代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Configuration; using System.Drawing.Printing; using System.IO; using System.Data; using System.Data.SqlClient; [assembly: TagPrefix("XTB_MSList", "XXW")] namespace XTB_MSList { [DefaultProperty("Text")] [ToolboxData("<{0}:XTB_MSList runat=server></{0}:XTB_MSList>")] public class XTB_MMSList : WebControl { #region Text属性 [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Text"] = value; } } #endregion #region 读取的表名称 public string Xtb_Name { get { String s = (String)ViewState["Xtb_Name"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Xtb_Name"] = value; } } #endregion #region 读取的HTML页面地址 public string Xtb_PathName { get { String s = (String)ViewState["Xtb_PathName"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Xtb_PathName"] = value; } } #endregion #region 读取数据库连接字符串的名称 public string Xtb_DName { get { String s = (String)ViewState["Xtb_DName"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Xtb_DName"] = value; } } #endregion #region 读取显示的行数 public string Xtb_Count { get { String s = (String)ViewState["Xtb_Count"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Xtb_Count"] = value; } } #endregion protected override void RenderContents(HtmlTextWriter output) { if (!DesignMode) { string connectString = ConfigurationManager.ConnectionStrings[Xtb_DName].ConnectionString; string htmls = GetInterIDList(Xtb_PathName); string outprint = DataListPrint(connectString, htmls); output.Write(outprint); } base.RenderContents(output); } /// <summary> /// 读取数据库,显示数据替换字符串输出到页面上 /// </summary> /// <param name="connectString">数据库连接字符串</param> /// <param name="htmls">静态页面的内容</param> public string DataListPrint(string connectString, string htmls) { string outprint = ""; var listName = TableList(htmls); char[] sp = { ','}; string[] listname = listName.Split(sp); string listkey = ""; for (int i = 0; i < listname.Length; i++) { listkey = listkey + listname[i].ToString() + ","; } listkey = listkey.Substring(0, listkey.Length - 1); string outhtmls = ""; if (listkey.Length > 1) { DataTable dt = DBHelp.GetDataTable("select top " + Xtb_Count + " " + listkey + " from " + Xtb_Name, connectString); for (int i = 0; i < dt.Rows.Count; i++) { for (int j = 0; j < listname.Length; j++) { if (j==0) outhtmls = htmls.Replace("{XTB_" + listname[j] + "}", dt.Rows[i][listname[j].ToString()].ToString()); else outhtmls = outhtmls.Replace("{XTB_" + listname[j] + "}", dt.Rows[i][listname[j].ToString()].ToString()); } outprint = outprint + outhtmls ; } } return outprint; } /// <summary> /// 提取前台要显示的字段名称,并返回LIST /// </summary> /// <param name="htmls">静态页面内容转化成的字符串</param> /// <returns>返回值 查询的字段数组</returns> public string TableList(string htmls) { string ListName = ""; int i = htmls.IndexOf("{XTB_"); string s = htmls.Substring(i, htmls.Length - i); for (int l = 0; s.IndexOf("{XTB_") != -1; l++) { i = s.IndexOf("{XTB_"); s = s.Substring(i, s.Length - i); string key = s.Substring(5, s.IndexOf("}") - 5); i = s.IndexOf("{XTB_"); s = s.Substring(i + 5, s.Length - i - 5); ListName += key + ","; } ListName = ListName.Substring(0, ListName.Length - 1); return ListName; } /// <summary> /// 读取html静态页面 /// </summary> /// <param name="strfile">页面名称或地址路径Xtb_PathName的属性值</param> /// <returns>返回值 静态页面内容</returns> public string GetInterIDList(string strfile) { string strout = ""; if (File.Exists(System.Web.HttpContext.Current.Server.MapPath(strfile))) { StreamReader sr = new StreamReader(System.Web.HttpContext.Current.Server.MapPath(strfile), System.Text.Encoding.Default); String input = sr.ReadToEnd(); sr.Close(); strout = input; } return strout; } } }
控件代码就到此结束,下面讲解使用过程:
需要使用控件时要先把生成的DLL文件引用到项目中去,
页面使用时需要输入如下代码<XXW:XTB_MMSList runat="server" Xtb_Count="5" Xtb_DName="SQLConnString" Xtb_Name="orders" Xtb_PathName="TEST.html" />
还有<%@ Register Assembly="XTB_MSList" Namespace="XTB_MSList" TagPrefix="XXW" %>
然后在Web.config文件中添加数据库连接字符串,连接字符串的name可以随意命名,示例:
<connectionStrings> <add name="SQLConnString" connectionString="Data Source=.;Initial Catalog=Northwind;integrated security=true" providerName="System.Data.SqlClient;Pooling=true;MAX Pool Size=512;Min Pool Size=50;Connection Lifetime=300"/> </connectionStrings>
aspx页面代码示例:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2"%> <%@ Register Assembly="XTB_MSList" Namespace="XTB_MSList" TagPrefix="XXW" %> <!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> <XXW:XTB_MMSList runat="server" Xtb_Count="5" Xtb_DName="SQLConnString" Xtb_Name="orders" Xtb_PathName="TEST.html" /> </div> </form> </body> </html>
根据aspx页面中自定义控件的Xtb_PathName="TEST.html" 在项目或相应的位置处添加文件test.html,在这里也可以设置成test.txt。只需要文件存在就
可以读取然后显示在页面上,也可以在这里设置好CSS,显示的时候会直接输出在页面上;
下面贴出test.html的代码:
<div> {XTB_CustomerID} </div> <div> {XTB_OrderDate} </div> <div> {XTB_ShippedDate} </div>
下面贴出我的测试页面输出后显示的代码如下:
<!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><title> </title></head> <body> <form method="post" action="Default2.aspx" id="form1"> <div class="aspNetHidden"> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTYyNzE4MTUzN2RkJXbGr7tDft0VFyhd4U01D5uCJLGK9q/ycTM2X8SWPnw=" /> </div> <div> <span><div> VINET </div> <div> 1996-7-4 0:00:00 </div> <div> 1996-7-16 0:00:00 </div> <br><div> TOMSP </div> <div> 1996-7-5 0:00:00 </div> <div> 1996-7-10 0:00:00 </div> <br><div> HANAR </div> <div> 1996-7-8 0:00:00 </div> <div> 1996-7-12 0:00:00 </div> <br><div> VICTE </div> <div> 1996-7-8 0:00:00 </div> <div> 1996-7-15 0:00:00 </div> <br><div> SUPRD </div> <div> 1996-7-9 0:00:00 </div> <div> 1996-7-11 0:00:00 </div> <br></span> </div> </form> </body> </html>
从代码可以看到控件的标签已经不存在,全部转化为要读取的数据显示在页面上。所以可以看做这个控件归根究底就是一种字符的替换,替换了原先的字符显示在
页面上。只是省去了中间的代码,当然 ,替换的代码也已经都封装在控件中。