首页 > 代码库 > Asp.Net服务器控件开发的Grid实现(二)

Asp.Net服务器控件开发的Grid实现(二)

我们先来实现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实现(二)》



Asp.Net服务器控件开发的Grid实现(二)