zoukankan      html  css  js  c++  java
  • 自定义控件的构建(9)

    前面重点介绍了ParseChildren特性,当其为False时,控件的内容会自动的解析成控件的子控件,这时控件内包含的所有内容都会添加到Controls集合中,

    而控件内任何非服务器控件将解析成Literal控件,某些时候可能仅允许一种控件被添加到Controls集合里。

    AddParsedSubObject()

    AddParsedSubObject()会在每个控件被添加进Controls集合中调用,通过重写该方法,可以阻止控件被添加进Controls集合。

    ControlBuilder

    ASP.NET框架在解析页面时,会使用到ControlBuilder类,因此可以给控件关联一个自定义的ControlBuilder类修改控件解析内容的行为,ControlBuilder类有几个比较常用的方法,可以查看MSDN,其中GetChildControlType()可以把任意标签映射成控件。

    看一段比较长的代码

        [ParseChildren(false)]
    
        [ControlBuilder(typeof(ServerTabsBuild ))]
    
        public class TabControl:WebControl,IPostBackEventHandler
    
        {
    
            public int SelectTabIndex
    
            {
    
                get 
    
                {
    
                    if (ViewState["SelectTabIndex"] == null)
    
                    {
    
                        return 0;
    
                    }
    
                    else
    
                    {
    
                        return (int)ViewState["SelectTabIndex"];
    
                    }
    
                }
    
                set
    
                {
    
                    ViewState["SelectTabIndex"] = value;
    
                }
    
            }
    
            protected override void AddParsedSubObject(object obj)
    
            {
    
                if (obj is ServerTab)
    
                {
    
                    base.AddParsedSubObject(obj);
    
                }
    
            }
    
            protected override HtmlTextWriterTag TagKey
    
            {
    
                get { return HtmlTextWriterTag.Div; }
    
            }
    
            
    
            protected override void RenderContents(HtmlTextWriter writer)
    
            {
    
                for (int i = 0; i < this.Controls.Count; i++)
    
                {
    
                  ServerTab tab=(ServerTab )this.Controls[i];
    
                  string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString());
    
                  if (SelectTabIndex == i)
    
                  {
    
                      writer.AddAttribute(HtmlTextWriterAttribute.Class, "tab selectedTab");
    
                   
    
                  }
    
                  else
    
                  {
    
                      writer.AddAttribute(HtmlTextWriterAttribute.Class, "tab");
    
                  }
    
                  writer.RenderBeginTag(HtmlTextWriterTag.Div);
    
                  writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef);
    
                  writer.RenderBeginTag(HtmlTextWriterTag.A);
    
                  writer.Write(tab.Text);
    
                  writer.RenderEndTag();
    
                  writer.RenderEndTag();
    
                }
    
                writer.Write("<br style='clear:both' />");
    
                writer.AddAttribute(HtmlTextWriterAttribute.Class, "tabContents");
    
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
    
                this.Controls[SelectTabIndex].RenderControl(writer);
    
                writer.RenderEndTag();
    
            }
    
            public void RaisePostBackEvent(string eventArgument)
    
            {
    
                SelectTabIndex = Int32.Parse(eventArgument);
    
            }
    
        }
    
        public class ServerTab : Control
    
        {
    
            public string Text { get; set; }
    
        }
    
        public class ServerTabsBuild : ControlBuilder
    
        {
    
            public override  Type  GetChildControlType(string tagName, IDictionary attribs)
    
            {
    
                if (String.Compare(tagName, "tab", true) == 0)
    
                {
    
                    return typeof(ServerTab);
    
                }
    
                else
    
                {
    
                    return null;
    
                }
    
            }
    
        }
    

    代码比较长,但是依然可以分析其逻辑,其中TabControl类被ControlBuilder修饰了,而该特性将TabControl关联到一个称为ServerTabsBuild

    的ControlBuilder类,ServerTabsBuild类则重写了GetChildControlType(),其作用是将<tab>映射成控件,也正是这个原因,在TabControl类

    声明选项卡时不再需要使用runat属性了。

    看看页面上的代码

     <mycustom:TabControl ID="TabControl" runat="server" >
    
         <tab Text="First">
    
          Hello!
    
         </tab>
    
          <tab Text="First">
    
          Hello!!
    
         </tab>
    
          <tab Text="First">
    
           Hello!!!
    
         </tab>
    
        </mycustom:TabControl>

    可以看到<tab>标签将<custom:Tab runat=”server”/>取代了。

    本文参考了《ASP.NET 3.5揭秘》

  • 相关阅读:
    [转] 分代垃圾回收的 新旧代引用问题(原标题:Back To Basics: Generational Garbage Collection)
    javascript中数组总结
    mybatis 与 反射
    mybatis 与 缓存
    mybatis 与 日志
    mybatis与 Exception
    mybatis 与 xml
    Redis -- 03 持久化
    Redis -- 02 配置文件解析
    【翻译】Crafting a Next-Gen Material Pipeline for The Order: 1886
  • 原文地址:https://www.cnblogs.com/626498301/p/1792742.html
Copyright © 2011-2022 走看看