Работа с главными страницами ASP.NET программными средствами

Visual Studio 2010

Обновлен: Ноябрь 2007

Существует возможность выполнения программными средствами с помощью главных страниц ряда типовых задач, включая следующие:

  • Вызов общих свойств и методов или элементов управления, определенных на главной странице.

  • Динамическое присоединение главных страниц к страницам содержимого.

Для обеспечения доступа к членам главной страницы класс Page предоставляет свойство Master. Для вызова членов конкретной главной страницы из страницы содержимого можно создать строго типизированную ссылку на главную страницу путем создания директивы @ MasterType. Директива позволяет указывать на конкретную главную страницу. Когда страница создает свое свойство Master, оно приводится к типу главной страницы, на которую указывает ссылка.

Например, предположим, что имеется главная страница с именем MasterPage.master, являющимся также именем класса MasterPage_master. Тогда можно создать директивы @ Page и @ MasterType, которые выглядят следующим образом:

<%@ Page  masterPageFile="~/MasterPage.master"%>

<%@ MasterType  virtualPath="~/MasterPage.master"%>

При использовании директивы @ MasterType, как в предыдущем примере, можно ссылаться на члены на главной странице, как показано в следующем примере:

CompanyName.Text = Master.CompanyName;

Свойство Master страницы уже приведено к типу MasterPage_master.

Получение значений из элементов управления на главной странице

Во время выполнения главная страница объединяется со страницей содержимого, поэтому элементы управления на главной странице становятся доступными для кода страницы содержимого. (Если в элементе управления ContentPlaceHolder главной страницы содержатся элементы управления, то эти элементы управления будут недоступными при переопределении их с помощью элемента управления Content страницы содержимого.) Эти элементы управления недоступны напрямую, как члены главной страницы, так как они защищены. Однако с помощью метода FindControl можно определять расположение определенных элементов управления на главной странице. Если элемент управления, к которому нужен доступ, находится внутри элемента управления ContentPlaceHolder на главной странице, необходимо сначала получить ссылку на элемент управления ContentPlaceHolder, а затем вызвать его метод FindControl, чтобы получить ссылку на нужный элемент управления.

В следующем примере показано, как можно получить ссылку на элементы управления главной страницы. Один из элементов управления, на который требуется ссылка, находится в элементе управления ContentPlaceHolder, а другой — нет.

// 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!";
    }
}

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

Можно получить доступ к содержимому элементов управления ContentPlaceHolder главной страницы с помощью метода FindControl, как показано выше. Если элемент управления ContentPlaceHolder был соединен с содержимым из элемента управления Content, то в элементе ContentPlaceHolder не будет того содержимого, которое задается по умолчанию. Вместо содержимого по умолчанию в этом элементе будут находиться текст и элементы управления, которые определены в странице содержимого.

Главную страницу можно задавать как путем объявления (в директиве @ Page или в файле конфигурации), так и путем динамического присоединения главной страницы к странице содержимого. Поскольку главная страница и страница содержимого объединяются на этапе инициализации обработки страниц, главная страница должна быть назначена до этого этапа. Обычно главная страница назначается динамически во время этапа PreInit, как в следующем примере:

void Page_PreInit(Object sender, EventArgs e)
{    this.MasterPageFile = "~/NewMaster.master";
}

Строгая типизация для динамических главных страниц

Если страница содержимого назначает главной странице строгий тип с помощью директивы @ MasterType, этот тип необходимо применить ко всем главным страницам, назначаемым динамически. Если предполагается динамический выбор главной страницы, то рекомендуется создать базовый класс, из которого будет производиться главная страница. Этот базовый класс главной страницы затем может определять свойства и методы главной страницы в целом. Если на странице содержимого назначается строгий тип главной страницы с помощью директивы @ MasterType, то можно назначать его не отдельной главной странице, а базовому классу главной страницы.

В следующих примерах показано, как создать базовый тип главной страницы, который может использоваться несколькими главными страницами. В этих примерах имеется базовый тип, производный от элемента управления MasterPage, две главные страницы, наследующие от базового типа, и страница содержимого, дающая пользователям возможность динамического выбора главной страницы с помощью строки запроса (?color=green). Базовый тип главной страницы определяет свойство с именем MyTitle. Одна из главных страниц из этих примеров переопределяет свойство MyTitle, а другая — нет. Страница содержимого отображает свойство MyTitle как заголовок страницы. Заголовок страницы, таким образом, будет изменяться в зависимости от выбранной главной страницы.

Это базовый тип главной страницы. Он принадлежит каталогу App_Code.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public class BaseMaster : System.Web.UI.MasterPage
{
    public virtual String MyTitle
    {
        get { return "BaseMaster Title"; }
    }
}

Это первая главная страница, которая отображает синий фон. Обратите внимание, что атрибут Inherits в директиве @ Master ссылается на базовый тип.

<%@ Master Language="C#" Inherits="BaseMaster" 
    ClassName="MasterBlue" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">
    // No property here that overrrides the MyTitle property of the base master.
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>No title</title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="background-color:LightBlue">
        <asp:contentplaceholder id="ContentPlaceHolder1" 
            runat="server">
        Content from MasterBlue.
        </asp:contentplaceholder>
    </div>
    </form>
</body>
</html>

Это вторая главная страница. Она такая же, как и первая главная страница, за исключением того, что отображает зеленый фон и переопределяет свойство MyTitle, которое определено в базовом типе.

<%@ Master Language="C#" Inherits="BaseMaster" 
    ClassName="MasterGreen" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<script runat="server">
    public override String MyTitle
    { 
        get { return "MasterGreen Title"; } 
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">   
    <title>No title</title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="background-color:LightGreen">
        <asp:contentplaceholder id="ContentPlaceHolder1" 
            runat="server">
            Content from MasterGreen.
        </asp:contentplaceholder>
    </div>
    </form>
</body>
</html>

Это страница содержимого, которая дает пользователям возможность выбирать главную страницу с помощью строки запроса. Директива @ MasterType, которая назначает строгий тип свойству Master страницы, ссылается на базовый тип.

<%@ Page Language="C#" Title="Content Page" MasterPageFile="~/MasterBlue.master"%>
<%@ MasterType TypeName="BaseMaster" %>
<script runat="server">
    protected void Page_PreInit(Object sender, EventArgs e)
    {
        this.MasterPageFile = "MasterBlue.master";
        if(Request.QueryString["color"] == "green")
        {
            this.MasterPageFile = "MasterGreen.master";
        }
        this.Title = Master.MyTitle;
    }
</script>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" 
        Runat="Server">
    Content from Content page.
</asp:Content>
Показ: