zoukankan      html  css  js  c++  java
  • 第二篇:呈现内容_第二节:WebControl呈现

    一、WebControl的呈现过程

    clipboard

    WebControl派生自Control类,所以WebControl的呈现功能基于Control的呈现逻辑之上,但有了比较大的扩展。

    首先,WebControl重写了Render(HtmlTextWriter writer)方法,将呈现的逻辑一分为三:RenderBeginTag()、RenderContents()、RenderEndTag()。WebControl的这种设计基于一种假设:每个WebControl最终生成一个HTML控件(当然这个HTML控件中可能还包含其他HTML子控件),所以WebControl的呈现过程就可分为:呈现开始标签、呈现标签中的内容和呈现结尾标签。

    protected internal override void Render(HtmlTextWriter writer)
    {
           this.RenderBeginTag(writer);
           this.RenderContents(writer);
           this.RenderEndTag(writer);
    }

    ①呈现开始标签:

    public virtual void RenderBeginTag(HtmlTextWriter writer)
    {
        this.AddAttributesToRender(writer);
        HtmlTextWriterTag htmlTextWriterTag = this.TagKey;
        if (htmlTextWriterTag != HtmlTextWriterTag.Unknown)
        {
            writer.RenderBeginTag(htmlTextWriterTag);
            return;
        }
        writer.RenderBeginTag(this.TagName);
    }

    由上面的实现代码可知:RenderBeginTag()方法所生成的HTML标签是由WebControl.TagKey或WebControl.TagName属性决定的。

    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    protected virtual HtmlTextWriterTag TagKey
    {
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        get
        {
            return this.tagKey;
        }
    }

    TagKey的类型为HtmlTextWriterTag 枚举,如果你的标签不在这个枚举中,则你需要把TagKey属性设为Unkown,并设置TagName属性,TagName属性为String类型,这意味着你可以将该属性设为任意值。

    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    protected virtual string TagName
    {
        get
        {
             if (this.tagName == null && this.TagKey != HtmlTextWriterTag.Unknown)
             {
                  this.tagName = Enum.Format(typeof(HtmlTextWriterTag), this.TagKey, "G").ToLower(CultureInfo.InvariantCulture);
             }
             return this.tagName;
         }
    }
    • 注意:在通常情况下,我们不重写RenderBeginTag()方法,而通过重写TagKeyTagName属性来实现对生成的外围HTML标签的控制。

    ②呈现标签中的内容:

    protected internal virtual void RenderContents(HtmlTextWriter writer)
    {
        base.Render(writer);
    }

    ③呈现结尾标签:

    public virtual void RenderEndTag(HtmlTextWriter writer)
    {
        writer.RenderEndTag();
    }

    到这里WebControl的呈现过程,都说完了,但有一个疑问是:最外围的HTML标签是怎么添加属性和样式属性的呢?

    相信细心的同学一定发现在WebControl类RenderBeginTag()方法中第一行代码:

    this.AddAttributesToRender(writer);

    故名思议就是添加属性到呈现内容,我们看下该方法的实现:

    protected virtual void AddAttributesToRender(HtmlTextWriter writer)
    {
        if (this.ID != null)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
        }
        if (this._webControlFlags[4])
        {
            string accessKey = this.AccessKey;
            if (accessKey.Length > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Accesskey, accessKey);
            }
        }
        if (!this.Enabled)
        {
            if (this.SupportsDisabledAttribute)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
            }
            if (this.RenderingCompatibility >= VersionUtil.Framework40 && !string.IsNullOrEmpty(WebControl.DisabledCssClass))
            {
                if (string.IsNullOrEmpty(this.CssClass))
                {
                    this.ControlStyle.CssClass = WebControl.DisabledCssClass;
                }
                else
                {
                    this.ControlStyle.CssClass = WebControl.DisabledCssClass + " " + this.CssClass;
                }
            }
        }
        if (this._webControlFlags[16])
        {
            int tabIndex = (int)this.TabIndex;
            if (tabIndex != 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, tabIndex.ToString(NumberFormatInfo.InvariantInfo));
            }
        }
        if (this._webControlFlags[8])
        {
            string toolTip = this.ToolTip;
            if (toolTip.Length > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Title, toolTip);
            }
        }
        if (this.TagKey == HtmlTextWriterTag.Span || this.TagKey == HtmlTextWriterTag.A)
        {
            this.AddDisplayInlineBlockIfNeeded(writer);
        }
        if (this.ControlStyleCreated && !this.ControlStyle.IsEmpty)
        {
            this.ControlStyle.AddAttributesToRender(writer, this);
        }
        if (this.attrState != null)
        {
            AttributeCollection attributes = this.Attributes;
            IEnumerator enumerator = attributes.Keys.GetEnumerator();
            while (enumerator.MoveNext())
            {
                string text = (string)enumerator.Current;
                writer.AddAttribute(text, attributes[text]);
            }
        }
    }

    首先,AddAttributesToRender()是一个虚方法,我们可以重写,又因为它在RenderBeginTag()开始时被调用,很显然我们可以将最外围的HTML标签添加属性和样式属性的逻辑在这里实现。其次,我们注意到WebControl类实现RenderBeginTag()方法时完成了(例如:Enabled与否,不同呈现)等基本的功能。所以在我们重写该方法为外围标签添加自定义属性和样式属性时,为了获得WebControl提供的基本功能。需在派生的控件类中调用父类的该方法:

    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
         base.AddAttributesToRender(writer);
         //......添加所需属性和样式的代码
    }

    二、从WebControl类派生"相册"控件

    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;
    namespace CustomServerControls
    {
        public class Albumn : WebControl
        {
            //(一):WebControl默认TagKey为span,这里重写为Div
            protected override HtmlTextWriterTag TagKey
            {
                get
                {
                    return HtmlTextWriterTag.Div;
                }
            }
            //(二:)为主标签(Div)添加一些样式属性
            protected override void AddAttributesToRender(HtmlTextWriter writer)
            {
                base.AddAttributesToRender(writer);
                writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "center");
                writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "194px");
                writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "194px");
                writer.AddStyleAttribute("background", "url(Images/background.gif) no-repeat left");
            }
            //(三):主标签的内容项是一个Img标签
            protected override void RenderContents(HtmlTextWriter writer)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Src, "Images/nature.jpg");
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "160px");
                writer.AddAttribute(HtmlTextWriterAttribute.Height,"160px");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "none");
                writer.AddStyleAttribute(HtmlTextWriterStyle.Padding, "0px");
                writer.AddStyleAttribute(HtmlTextWriterStyle.MarginTop, "16px");
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
        }
    }
  • 相关阅读:
    JQuery计算当前Dom结构在浏览器窗口中被显示方法(懒加载原理)
    图片png24格式在IE6下半透明解决办法
    CSS方式支持IE6的fixed样式
    ecshop模板首页或列表页显示商品简单描述
    ecshop静态、 ecshop伪静态、ecshop伪静态设置详细方法、ECSHOP静态化方法
    批量清除ecshop全部商品的精品 新品和热销属性的方法
    ecshop商品页显示累计销售量,ecshop显示商品销售总数量的方法
    常用JQuery插件整理、前端适用
    ecshop销售排行榜显示销售 销量的商品的件数方法
    Ecshop IIS Rewrite伪静态规则
  • 原文地址:https://www.cnblogs.com/hanzhaoxin/p/4055422.html
Copyright © 2011-2022 走看看