A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

50分钟的视频,看了一次没看懂,第二次看了三个小时,一边看一边记笔记,终于搞懂了,其实就是个很简单的概念,只是讲太快没缓过劲

分享下笔记:
       控件树的生成
                                                                ——页面类对象,通过控件树的方式,帮我们封装了整个页面的HTML源代码和C#代码
                                                                        (都封装到页面类对象的控件集合属性中,那么要生成HTML代码的时候,只需要循环遍历整个控件树,并调用每个控件的__Render__(呈现)方法获得每个控件的HTML代码,就可以拼成一个完整的HTML代码了。)


        *前台页面最上方有  Inherist(继承) = "类名"  指定了前台页面类继承的对象
                                                                                    
        *如果C盘没有程序集,浏览器访问网站的时候,服务器会自动把网站编译成程序集(DLL)

                浏览器请求————》服务器在内存中找网站程序集————》没有的就到C盘找————》没有就编译

        *编译好的程序集中有两个比较熟悉的类,一个是以 页面名 命名的类,一个是以 页面名_aspx 命名的类(通过反编译网站程序集看到)


1.FirstForm(页面名)类   (后台文件类)
       
        *对应了我们编写的后台文件里的内容

        *继承于Page类,并实现了 IRequiresSessionState 接口

        *后台文件类之所以能通过 this.控件ID 调用前台页面控件,是因为前台控件(runat="server" 的控件)是以后台文件类变量的方式存在的。前台页面类也可以访问到父类(后台文件类)的非私有成员(方法、属性),通过写在前台页面<%%>中实现

        *当浏览器请求该页面的时候,服务器通过反射在程序集中创建出 前台页面类对象,由于前台页面类继承于 后台文件类,所以编译器会自动创建出它的父类对象——后台文件类

2.前台页面类
       
        *前台页面类中有个名为 __BuidControlTree 的方法,页面被请求的时候,通过调用该方法来组织整个页面的HTML代码(创建控件树)

3.控件树
       
        *控件就是一个对象

        *控件树负责整个页面的内容(前台页面类中的 __BuidControlTree 方法 )

        *在浏览器中的DOM树中,每个节点都有一个 childNodes集合 属性,用来保存当前节点的子节点
                (每一个节点中都必须有一个子节点集合,这样才能生成一颗树)

        *在.net中生成控件树的时候,也必须要生成一个个的对象,这些对象里面,也必须包含子控件集合,以方便的安装子控件

        *在__BuidControlTree方法中,传入了当前页面对象(__ctrl),并把该对象转成了一个 IParserAccessor 接口,该接口中有一个名为 AddParsedSubObject的方法(添加子节点),由此可知,当前页面对象(__ctrl)中,肯定会有一个集合,用来存放子节点

        *该集合在它(前台页面类)的父类 后台页面类 的父类 Page 的父类 TemplateControl 的父类 Control类中,名字为 ControlCollection 的集合

        *页面本身就是控件,它的属性 ControlCollection集合(存在于父类Control中) 存放了它的子控件
       
        *__BuildControlTree方法首先给该集合添加了一个 LiteralControl 对象,它里面存放的是HTML最上方的那段HTML代码(从 <!DOCTYPE 一直到 <html> 的开始标签),该标签下方的<head>中有 runat="server" ,head将作为一个对象存放在集合里面,所以上面的html代码都作为字符串封装到了 LiteralControl 中,并将它作为一个子节点保存在集合中,可以把 LiteralControl 理解为一个字符串控件

        *添加了 runat="server" 的控件,编译之后,就会变成一个相对应类型的对象,并作为子节点存入集合中

        *创建HtmlHead对象的时候,调用了this.__BuildControl__control2方法,该方法中,new了一个名为head的HtmlHead对象,并在该方法中调用this.__BuildControl__control3方法,创建了一个名为title的HtmlTitle的对象,随后把head转成IParserAccessor接口,将title加入head的控件集合中,返回head

        *在 __BuildControl__control3中,返回了一个专门的类型 HtmlTitle

        *head创建完成后,被转成接口的当前页面的对象(__ctrl)调用AddParsedSubObject方法,把head加入到集合中

        *因为<body>并没有 runat="server" ,所以把它封装在LiteralControl中,并加入集合

        *在 __BuildControlTree 方法中,调用 __BuildControlform1 方法,创建了页面中ID=form1的表单的对象,加入当前页面集合

        *由于<body>是作为文本对象存在的,不会有自己的子节点,所以<body>中的有runat="server"的<form>表单对象被加入了当前页面的集合中(如果form表单没有runat="server",那么也将被封装成字符串控件加入到当前页面的集合中,而它有runat="server"的子节点将作为对象直接存入当前页面的集合中————自己猜的)

        *在 __BuildControlform1方法中,首先创建了form对象,并给父类(后台文件类)中的属性from1赋值(base.form1 = form;),随后分别创建了表单中的其他节点,把form对象转成 IParserAcessor 接口,并调用 AddParsedSubObject 方法,把属于 form的对象加入到 form对象的集合中,返回form

        *在返回form之前,有一句非常重要的代码 (form.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));),它向当前表单对象追加了一个委托,委托上注册了一个方法(__Renderform1),该方法中,执行了前台页面中<%%>中的代码,并将没有runat="server"的控件直接以字符串的形式呈现,还调用了from的集合中的元素(有runat="server"的属于form1表单的服务器控件的对象)的呈现(RenderControl)方法,将它们加入到浏览器的缓存中(HtmlTextWriter)
                (在前台页面<%%>中有“=”或有"Response.Write”的时候,就有可能在控件树里面调用控件对象的呈现委托方法,向里面追加一个呈现的方法)
                        (服务器控件的对象,都有对应的呈现方法,而<$=$>中的代码却没有,只能追加一个呈现方法,执行代码,把结果转成HTML代码)

        *呈现————将服务器端控件类对象转成对应的html代码

        *form表单对象创建完毕后,将之加入当前页面类的集合中(通过转成IParserAcessor接口的对象调用AddParsedSubObject方法)

        *由于演示页面已经没有内容了,所以最后将</body>等html结束代码封装到LiteralControl字符串控件中,加入当前页面类的集合中,控件树创建完毕
视频为 ASP.NET 中级教程中的 黑马程序员.NET训练营ASP.NET视频教程WebForm页面生命周期03_WEBFORM_ASPNET控件树的生成和作用

评分

参与人数 1技术分 +2 收起 理由
宋天琪 + 2

查看全部评分

1 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马