• 自定义控件的构建(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揭秘》

  • 相关阅读:
    Codeforces 17.E Palisection
    poj4052 Hrinity
    bzoj2565 最长双回文串
    Java基础知识强化之集合框架笔记43:Set集合之TreeSet存储Integer类型的元素并遍历
    Java基础知识强化之集合框架笔记42:Set集合之LinkedHashSet的概述和使用
    Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习
    Java基础知识强化之集合框架笔记40:Set集合之HashSet存储自定义对象并遍历
    TCP/IP协议原理与应用笔记13:底层网络技术之传输介质
    Java基础知识强化之集合框架笔记39:Set集合之HashSet存储字符串并遍历
    Java基础知识强化之集合框架笔记38:Set集合之Set集合概述和特点
  • 原文地址:https://www.cnblogs.com/626498301/p/1792742.html
Copyright © 2020-2023  润新知