Asp.net自定义控件开发任我行(3)-Render

  • 摘要  

  上一篇我们讲到了自定义标签TagPrefix用法,此篇我们来讲一下控件的呈现,主要是呈现下拉框

  • 内容

  呈现的方法有,Render,RenderControl,RenderChildren,这三个方法,其实我也最近才搞明白的,生怕自己忘记,所以就在记下来了,以前学Asp.net页面生命周期的时候,对这些更是一知半解,对此是耿耿于怀,如鲠在喉 ,现在总算是把疑问解决了。

  我们先来看看这三个方法底层的实现方法吧,下面是Control类的呈现方式  

     protected internal virtual void Render(HtmlTextWriter writer)
        {
            this.RenderChildren(writer);
        }
        
        protected internal virtual void RenderChildren(HtmlTextWriter writer)
        {
            ICollection children = this._controls;
            this.RenderChildrenInternal(writer, children);
        }
        
        internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
        {
            if ((this.RareFields != null) && (this.RareFields.RenderMethod != null))
            {
                writer.BeginRender();
                this.RareFields.RenderMethod(writer, this);
                writer.EndRender();
            }
            else if (children != null)
            {
                foreach (Control control in children)
                {
                    control.RenderControl(writer);
                }
            }
        }
        
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public virtual void RenderControl(HtmlTextWriter writer)
        {
            this.RenderControl(writer, this.Adapter);
        }
        
        protected void RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
        {
            if (!this.flags[0x10] && !this.flags[0x200])
            {
                HttpContext context = (this.Page == null) ? null : this.Page._context;
                if ((context != null) && context.TraceIsEnabled)
                {
                    int bufferedLength = context.Response.GetBufferedLength();
                    this.RenderControlInternal(writer, adapter);
                    int num2 = context.Response.GetBufferedLength();
                    context.Trace.AddControlSize(this.UniqueID, num2 - bufferedLength);
                }
                else
                {
                    this.RenderControlInternal(writer, adapter);
                }
            }
            else
            {
                this.TraceNonRenderingControlInternal(writer);
            }
        }
        
        private void RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
        {
            try
            {
                this.BeginRenderTracing(writer, this);
                if (adapter != null)
                {
                    adapter.BeginRender(writer);
                    adapter.Render(writer);
                    adapter.EndRender(writer);
                }
                else
                {
                    this.Render(writer);
                }
            }
            finally
            {
                this.EndRenderTracing(writer, this);
            }
        }

代码是不是太长啦。。。看得很烦。说穿了,他们的调用顺序是:首先调用RenderControl方法,RenderControl方法里面调用Render方法,Render方法调用RenderChildren方法,RenderControl也是通过一个循环遍历子控件,每遍历一次调用RenderControl一次,直到子控件全部被遍历完。
详情请见:http://wenku.baidu.com/view/13db1afdfab069dc502201b9.html

一般情况下,我们都只重写Render方法,其他两个方法最好别碰。

  现在我们来呈现一个下拉框,我们来分析一下,下拉框,我们可以理解为一个Div,其实我们最主要的目的就是呈现一个下拉框

using System;
using System.Text;
using System.Web.UI;
using System.ComponentModel;//包含组件开发所必须含有的(属性)Attribute;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

namespace XYB.Controls
{
    public class TextEdit:TextBox
    {
        private int _dropDwonHeight;
        [Description("下拉框的高度"),//属性的描述
         Category("下拉框")//所属目录
        ]
        public int DropDwonHeight
        {
            get { return _dropDwonHeight; }
            set { _dropDwonHeight = value; }
        }
        private int _dropdwonWidth;
        [Description("下拉框的宽度"),
         Category("下拉框")
        ]
        public int DropdwonWidth
        {
            get { return _dropdwonWidth; }
            set { _dropdwonWidth = value; }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
            Panel pnlDropDown = new Panel();
            pnlDropDown.ID = "pnlDropDownID";
            pnlDropDown.Height = DropDwonHeight;
            pnlDropDown.Width = DropdwonWidth;
            pnlDropDown.Style["border"] = "1px solid #ccc";//设置边框样式
            pnlDropDown.RenderControl(writer);//把下拉框呈现到网页上
        }        
    }
}

Asp.net自定义控件开发任我行(3)-Render

本章结束,

  • 下集预告

  ViewState视图保存属性状态,敬请大家关注我!