我们先来实现Grid类,代码如下:
Grid.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI; namespace AspNetServerControl { [Designer("AspNetServerControl.Design.GridDesigner, AspNetServerControl.Design")]//设计时支持,需要另外写一个对就的类 [ToolboxData("<{0}:Grid Title=\"Grid\" runat=\"server\"><Columns></Columns></{0}:Grid>")] [ToolboxBitmap(typeof(Grid), "toolbox.Grid.bmp")] [Description("表格控件")] [ParseChildren(true)] [PersistChildren(false)] [ControlBuilder(typeof(NotAllowWhitespaceLiteralsBuilder))] public class Grid : ControlBase { #region 属性 #region DataSource private object _dataSource; public object DataSource { get { return _dataSource; } set { _dataSource = value; } } #endregion #region Columns private GridColumnCollection _columns; /// <summary> /// 列数据 /// </summary> [Category(CategoryName.OPTIONS)] [NotifyParentProperty(true)] [PersistenceMode(PersistenceMode.InnerProperty)] [Editor(typeof(GridColumnsEditor), typeof(System.Drawing.Design.UITypeEditor))]//用于编辑器 public virtual GridColumnCollection Columns { get { if (_columns == null) { _columns = new GridColumnCollection(this); } return _columns; } } #endregion #endregion protected override void Render(HtmlTextWriter writer) { base.Render(writer); if (_columns == null) { return; } writer.Write("<table border=\"1\" cellspacing=\"0\">"); RenderHeader(writer); RenderBody(writer); writer.Write("</table>"); } private void RenderHeader(HtmlTextWriter writer) { writer.Write("<tr>"); foreach (GridColumn column in Columns) { writer.Write(String.Format("<th >{0}</th>", column.HeaderText)); } writer.Write("</tr>"); } private void RenderBody(HtmlTextWriter writer) { DataTable dt = DataSource as DataTable; if (dt == null || dt.Rows.Count <= 0) { return; } writer.Write("<tbody>"); foreach (DataRow row in dt.Rows) { writer.Write("<tr >"); foreach (GridColumn column in Columns) { writer.Write(String.Format("<td >{0}</td>", row[column.DataField])); } writer.Write("</tr>"); } writer.Write("</tbody>"); } } }1.Grid类前面的几个属性相当重要:
(1).Designer是设计时支持,需要另外写一个类库来支持。
(2).ParseChildren指示页分析器应如何处理页上声明的服务器控件标记中嵌套的内容,也就是这个属性决定了Grid内部还可以再嵌套其他内容(为true时才可嵌套),比如Columns。
2.继承自ControlBase,该类后面会介绍。
3.DataSource属性是数据源。
4.Columns是Grid的内部列,其中[Editor(typeof(GridColumnsEditor), typeof(System.Drawing.Design.UITypeEditor))]这个特性非常重要,该特性指示了该属性Columns可以在编辑中编辑。其中GridColumnsEditor是界面编辑的类,后面会介绍。
5.重载Render方法。该方法是将Grid最终html形式输出。这里以table的形式来实现Grid。
(1)将Columns中的所有列的列名以table中的th呈现
(2)将数据源转换成DataTable,然后遍历每一行,并将每一行的数据以td的形式呈现。
下面来看一下ControlBase类。
ControlBase.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI; namespace AspNetServerControl { public class ControlBase : Control, INamingContainer { } }ControlBase类继承自Control类及INamingContainer接口,这是自定义控件所必须的。
再来看一下NotAllowWhitespaceLiteralsBuilder类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI; namespace AspNetServerControl { /// <summary> /// 控件内部不允许存在非标签形式的字符串 /// </summary> internal class NotAllowWhitespaceLiteralsBuilder : ControlBuilder { /// <summary> /// 不允许空白字符 /// </summary> /// <returns></returns> public override bool AllowWhitespaceLiterals() { return false; } /// <summary> /// 忽略游离于标签外的字符串 /// </summary> /// <param name="s"></param> public override void AppendLiteralString(string s) { } public override Type GetChildControlType(string tagName, System.Collections.IDictionary attribs) { return base.GetChildControlType(tagName, attribs); } } }NotAllowWhitespaceLiteralsBuilder主要是用来控制控件内部不允许存在非标签形式的字符串。
后面将会说明GridColumnsEditor及GridColumn字段的定义,具体请看《Asp.Net服务器控件开发的Grid实现(二)》
原文地址:http://blog.csdn.net/xxdddail/article/details/40589115