zoukankan      html  css  js  c++  java
  • ASP.NET母版页

    使用 ASP.NET 母版页可以为应用程序中的页创建一致的布局。单个母版页可以为应用程序中的所有页(或一组页)定义所需的外观和标准行为。然后可以创建包含要显示的内容的各个内容页。当用户请求内容页时,这些内容页与母版页合并以将母版页的布局与内容页的内容组合在一起输出。

    母版页为具有扩展名 .master(如 MySite.master)的 ASP.NET 文件,它具有可以包括静态文本、HTML 元素和服务器控件的预定义布局。母版页由特殊的 @ Master 指令识别,该指令替换了用于普通 .aspx 页的 @ Page 指令。该指令类看起来类似下面这样。
    <%@ Master Language="C#" %>
    除会在所有页上显示的静态文本和控件外,母版页还包括一个或多个ContentPlaceHolder控件。这些占位符控件定义可替换内容出现的区域。接着在内容页中定义可替换内容。

    内容页
       通过创建各个内容页来定义母版页的占位符控件的内容,这些内容页为绑定到特定母版页的 ASP.NET 页(.aspx 文件以及可选的代码隐藏文件)。通过包含指向要使用的母版页的 MasterPageFile 属性,在内容页的 @ Page 指令中建立绑定。例如,一个内容页可能包含下面的 @ Page 指令,该指令将该内容页绑定到 Master1.master 页。在内容页中,通过添加 Content 控件并将这些控件映射到母版页上的 ContentPlaceHolder 控件来创建内容。

    <% @ Page Language="C#" MasterPageFile="~/Master.master" Title="Content Page 1" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="Server">
        Main content.
    </asp:Content>

    母版页中创建为 ContentPlaceHolder 控件的区域在新的内容页中显示为 Content 控件。

    显示剩下的母版页内容,以便您查看布局,但这些内容显示为浅灰色,因为您在编辑内容页时不能更改这些内容。

    母版页具有下面的优点:
    1.使用母版页可以集中处理页的通用功能,以便可以只在一个位置上进行更新。
    2.使用母版页可以方便地创建一组控件和代码,并将结果应用于一组页。例如,可以在母版页上使用控件来创建一个应用于所有页的菜单。
    3.通过允许控制占位符控件的呈现方式,母版页使您可以在细节上控制最终页的布局。
    4.母版页提供一个对象模型,使用该对象模型可以从各个内容页自定义母版页。

    母版页的运行时行为
    在运行时,母版页是按照下面的步骤处理的:

    1.用户通过键入内容页的 URL 来请求某页。
    2.获取该页后,读取 @ Page 指令。如果该指令引用一个母版页,则也读取该母版页。如果这是第一次请求这两个页,则两个页都要进行编译。
    3.包含更新的内容的母版页合并到内容页的控件树中。
    4.各个 Content 控件的内容合并到母版页中相应的 ContentPlaceHolder 控件中。
    5.浏览器中呈现得到的合并页。

     

    如何:引用 ASP.NET 母版页的内容

    可以在内容页中编写代码来引用母版页中的属性、方法和控件,但这种引用有一定的限制。对于属性和方法的规则是:如果它们在母版页上被声明为公共成员,则可以引用它们。这包括公共属性和公共方法。在引用母版页上的控件时,没有只能引用公共成员的这种限制。

    引用母版页上的公共成员
    1.在内容页中添加 @ MasterType 指令。在该指令中,将 VirtualPath 属性设置为母版页的位置,如下面的示例所示:<%@ MasterType virtualpath="~/Masters/Master1.master" %> 此指令使内容页的 Master 属性被强类型化。
    2.编写代码,将母版页的公共成员用作 Master 属性的一个成员,如本例中,将母版页名为 CompanyName 的公共属性的值赋给内容页上的一个文本框

     

    引用母版页上的控件
    使用 FindControl 方法,将 Master 属性的返回值用作命名容器。

    下面的代码示例演示如何使用 FindControl 方法获取对母版页上的两个控件的引用(一个 TextBox 控件和一个 Label 控件)。因为 TextBox 控件处在 ContentPlaceHolder 控件的内部,必须首先获取对 ContentPlaceHolder 的引用,然后使用其 FindControl 方法来定位 TextBox 控件。
    void Page_Load()
    {
        // Gets a reference to a TextBox control inside
        // a ContentPlaceHolder
        ContentPlaceHolder mpContentPlaceHolder;
        TextBox mpTextBox;
        mpContentPlaceHolder =
          (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
        if(mpContentPlaceHolder != null)
        {
            mpTextBox =
                (TextBox) mpContentPlaceHolder.FindControl("TextBox1");
            if(mpTextBox != null)
            {
                mpTextBox.Text = "TextBox found!";
            }
        }

    母版页是VS2005中新引入的一个概念,它很好地实现界面设计的模块化,并且实现实现了代码的重用。它就像婚纱影楼中的婚纱模板,同一个婚纱模板可以给不同的新人用,只要把他们的照片贴在已有的婚纱模板就可以形成一张漂亮的婚纱照片,这样可以大大简化婚纱艺术照的设计复杂度。这里的母版页就像婚纱模板,而内容页面就像两位新人的照片。
    在VS2003中没有母版页,要实现这种设计重用的效果,我们只能用“用户控件”来实现,但用户控件没有一种可视化的组合外观,使用起来不太方便。

    母版页(扩展名是.master)
    它的使用跟普通的页面一样,可以可视化的设计,也可以编写后置代码。与普通页面不一样的是,它可以包含ContentPlaceHolder控件,ContentPlaceHolder控件就是可以显示内容页面的区域。
    代码如下:
    <%@ Master Language="C#" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
    ......
        <form id="form1" runat="server">
        <div>
            <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
            </asp:contentplaceholder>
        </div>
        </form>
    ......

    注意:
        1、这里的声明指示符是“<%@ Master...%>”
        2、其内部包含<asp:contentplaceholder......>控件

    内容页(扩展名是.aspx)
    在建立内容页面的时候,在“添加新项”对话框中要选中“选择母版页”复选框。这样建立的页面就是内容页面,内容页面在显示的时候会把母版面的内容一起以水印淡化的形式显示出来,而在母版页中的ContentPlaceHolder控件区域会被内容页面中的Content控件替换,程序员可以在这里编写内容页面中的内容。
    代码如下:
    <%@ Page Language="C#" MasterPageFile="~/MasterPage/MP.master" CodeFile="Show1.aspx.cs" Inherits="MasterPage_Show1" Title="Untitled Page" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    </asp:Content>

     

    注意:
        1、这里的声明指示符中多了一项MasterPageFile="~/MasterPage/MP.master",这一项是在创建内容页面时根据“选择母版页”复选框的选中情况生成的。它指明了该页是内容页面,也指明了该内容页面的母版页是哪个页面。
        2、“<asp:Content ......>”就是要在其中显示的内容。

    一、在母版页中编写后台代码,访问母版页中的控件:
        与普通的aspx页面一样,双击按钮即可编写母版页中的代码
       
    二、在内空页面中编写后台代码,访问内容页面中的控件:
        与普通的aspx页面一样,双击按钮即可编写母版页中的代码
       
    三、在内容页面中编写代码访问母版页中的控件:
        在内容页面中有个Master对象,它是MasterPage类型,它代表当前内容页面的母版页。通过这个对象的FindControl方法,我们可以找到母版面中的控件,这样就可以在内容页面中操作母版页中的控件了。
            TextBox txt = (TextBox)((MasterPage)Master).FindControl("txtMaster");
            txt.Text = this.txtContent1.Text; ;
           
    四、在内容页面中编写代码访问母版页中的属性和方法:
        仍可能通过Master对象进行访问,只不过在这里要把Master对象转换成具体的母版页类型,然后再调用母版页中的属性和方不法。
        这里要说明的是:母版页中要被内容页面调用的属性和方法必须是Public修改的。否则无法调到。
            假设母版页中有下面的属性和方法:
            public string TextValue
            {
                get
                {
                    return this.txtMaster.Text;
                }
                set
                {
                    this.txtMaster.Text = value;
                }
            }
            public void show(string str)
            {
                txtMaster.Text = str;
            }
           在内容页面中可以通过下代的代码来实现对母版页中方法的调用:
            ((MasterPage_MP)Master).show(this.txtContent1.Text);
            ((MasterPage_MP)Master).TextValue = this.txtContent1.Text;
           
    五、在母版页中访问内容页面的控件:
        在母版页中可以通过在ContentPlaceHolder控件中调用FindControl方法来取得控件,然后对控件进行操作。
        ((TextBox)this.ContentPlaceHolder1.FindControl("txtContent1")).Text = this.txtMaster.Text;
       
    六、在母版页中访问内容页面中的方法和属性:
        在母版页中调用子页面中的属性和方法有点难度,因为我们无法像上一步中那样通过FindControl来找到方法和属性。
        于是我们想到在母版面的声明指示符中加入下面的代码:
            <%@ Reference Page="~/MasterPage/Show1.aspx" %>
        在运行的时候回发现有错误,错误的内容是“无法实现循环引用”。这是因为默认在子页面中引用了母版页,你也就不能再在母版页中引用子页面了。
        我在网上也没找到更好的解决方法,但这使我们想起C#是的“反射”,它可以使我们动态获取页面对象,并且可以调用它的属性和方法。
        代码如下:
            Type t = this.ContentPlaceHolder1.Page.GetType();
            PropertyInfo pi = t.GetProperty("ContentValue"); //获取ContentValue属性
            pi.SetValue(this.ContentPlaceHolder1.Page,this.txtMaster.Text,null);    //给属性赋值
           
            MethodInfo mi = t.GetMethod("SetValue"); //获取SetValue()方法
            object[] os = new object[1];   //建造输入参数
            os[0] = txtMaster.Text;
            mi.Invoke(this.ContentPlaceHolder1.Page, os);    //调用SetValue方法
           
    七、在有多个内容页面使用母版面的情况下,在母版页中根据不同的内容页面实现不同的操作
        在母版页中可以加入多个不同的内容页面,但在设计期间,我们无法知道当前运行的是哪个内容页面。所以只能通过分支判断当前运行的是哪个子页面,来执行不同的操作。这里也用到了反射的知识。
        代码如下:
            string s = this.ContentPlaceHolder1.Page.GetType().ToString();   //取出内容页面的类型名称
            if (s == "ASP.default17_aspx")   //根据不同的内容页面类型执行不同的操作
            {
                ((TextBox)this.ContentPlaceHolder1.FindControl("TextBox2")).Text = "MastPage";
            }
            else if (s == "ASP.default18_aspx")
            {
                ((TextBox)this.ContentPlaceHolder1.FindControl("TextBox2")).Text = "Hello MastPage";
            }
    八、在母版面与内容页面中JS代码的操作
        在母版页或内容页面中的控件运行之后会自动生成ID,如文本框的ID是txtContent1,在运行之后ID会自动变为ctl00_ContentPlaceHolder2_txtContent1,name属性会变为ctl00$ContentPlaceHolder2$txtContent1。
        在JS代码中,我们用document.getElementByIdx()方法,根据id取得控件对象的时候,应当使用ctl00_ContentPlaceHolder2_txtContent1这个ID名,否则会产生“未找到对象”的异常。

    母版页运行机制
    母版页仅仅是一个页面模板,单独的母版页是不能被用户所访问的。单独的内容页也不能够使用。母版页和内容页有着严格对应关系。母版页中包含多少个ContentPlaceHolder控件,那么内容页中也必须设置与其相对应的Content控件。当客户端浏览器向服务器发出请求,要求浏览某个内容页面时,ASP.NET引擎将同时执行内容页和母版页的代码,并将最终结果发送给客户端浏览器。
    母版页和内容页的运行过程可以概括为以下5个步骤。
    (1)用户通过键入内容页的URL来请求某页。
    (2)获取内容页后,读取@ Page指令。如果该指令引用一个母版页,则也读取该母版页。如果是第一次请求这两个页,则两个页都要进行编译。
    (3)母版页合并到内容页的控件树中。
    (4)各个Content控件的内容合并到母版页中相应的ContentPlaceHolder控件中。
    (5)呈现得到结果页。

    母版页和内容页事件顺序

     

    (1)母版页中控件Init事件;
    (2)内容页中Content控件Init事件;
    (3)母版页Init事件;
    (4)内容页Init事件;
    (5)内容页Load事件;
    (6)母版页Load事件;
    (7)内容页中Content控件Load事件;
    (8)内容页PreRender事件;
    (9)母版页PreRender事件;
    (10)母版页控件PreRender事件。
    (11)内容页中Content控件PreRender事件。

    使用母版页的优点:
    (1)有利于站点修改和维护,降低开发人员的工作强度
    (2)有利于实现页面布局
    (3)提供一种便于利用的对象模型

        
        // Gets a reference to a Label control that not in
        // a ContentPlaceHolder
        Label mpLabel = (Label) Master.FindControl("masterPageLabel");
        if(mpLabel != null)
        {
            Label1.Text = "Master page label = " + mpLabel.Text;
        }
    }

  • 相关阅读:
    2020 camp day0 -F
    2020 camp day2 -k
    扫描线 hdu1542
    Assign the task HDU
    快速排序模板
    Java中Thread的常用方法
    Java中多线程的创建
    二分模板
    main()的简单理解
    单例模式饿汉式和懒汉式的实现
  • 原文地址:https://www.cnblogs.com/wuhuisheng/p/2003369.html
Copyright © 2011-2022 走看看