内容页和母版页之间的交互
讨论内容页与母版页之间交互的概念和实现。
引言
人们希望内容页和其关联的母版页之间的交互能够自动发生,因为内容页和母版页在被渲染到客户端浏览器之前会由.NET框架一起编译。不幸的是,要实现这一点,需要额外的编程工作。.NET框架通过几个步骤使得实现起来相对容易,如下所示。
首先,在内容页的开头放置一个MasterType
指令,以建立内容页与其母版页之间的通信链接。
<%@ MasterType VirtualPath="~/MasterPage.master" %>
MasterPage.master是母版页的文件名。这个指令在内容页上启用一个“Master对象”,它提供了一个用于交互的编程接口。根据微软的文档,Master
是Page
类的一个属性。由于它像一个对象一样工作,为了便于阅读,我们将其称为Master
对象。
其次,通过公共属性和方法公开母版页上的服务器控件。这些属性和方法在内容页的Master
对象上作为公共成员呈现。内容页通过访问这些属性和方法与母版页进行通信。
第三,通过Master
对象将母版页的服务器控件的事件连接到内容页。母版页通过事件处理程序与内容页进行通信。
通信场景
内容页与母版页之间的基本交互可以是内容页与母版页通信,或者母版页与内容页通信。为了说明交互是如何真正工作的,准备了一个演示应用程序供下载。
如上屏幕截图所示,顶部区域有两个TextBox
控件和两个Button
控件,颜色为蓝色,并由蓝色矩形框起来。这些是母版页上的服务器控件。同样,截图的下半部分显示了两个TextBox
控件和两个Button
控件,颜色为栗色。这些是内容页上的服务器控件。
在母版页区域,单击MasterButton1,Master Box 1中的文本将被发送到Content Box 1。单击MasterButton2,母版页将从Content Box 2检索文本并将其显示在Master Box 2中。在内容区域,ContentButton1将内容页中的文本发送到母版页,而ContentButton2将母版页中的文本检索到内容页。
这个应用程序虽然相对简单,但说明了内容页与其相关母版页之间常见的交互场景。
内容页与母版页交互
母版页上的服务器控件仅限于母版页本身,内容页无法访问。为了使它们可访问,需要将服务器控件公开为公共属性或方法。以下代码示例为母版页上的两个TextBox
控件和两个Button
控件创建了四个公共属性,并公开了四个方法,用于为TextBox
控件赋值或检索值。为了清晰起见,在每个属性名称前面都加上了“Property”一词。根据项目需求,属性可以是只读、只写或读写的。如果需要,还可以实现更多方法。
//expose controls on master page as public properties
public TextBox PropertyMasterTextBox1
{
get { return txtMasterBox1; }
set { txtMasterBox1 = value; }
}
public TextBox PropertyMasterTextBox2
{
get { return txtMasterBox2; }
set { txtMasterBox2 = value; }
}
public Button PropertyMasterButton1
{
get { return btnMasterButton1; }
}
public Button PropertyMasterButton2
{
get { return btnMasterButton2; }
}
//expose public methods on master page for content page to call
public void SetMasterBox1Value(string myText)
{
txtMasterBox1.Text = myText;
}
public string GetMasterbox1Value()
{
return txtMasterBox1.Text;
}
public void SetMasterBox2Value(string myText)
{
txtMasterBox2.Text = myText;
}
public string GetMasterBox2Value()
{
return txtMasterBox2.Text;
}
在内容页上,上述属性和方法可以被视为Master
对象的公共成员。下面的代码列表显示了内容页的btnContentButton1
点击事件处理程序,该处理程序将Content Box 1(栗色)中的文本发送到Master Box 1(蓝色)。可选地,可以使用母版页的属性或方法来完成此操作。在选项1中,txtContentBox1
的值通过公共属性Master.PropertyMasterTextBox1
赋给Master Box 1,而在选项2中,调用公共方法Master.SetMasterBox1Value()
来实现相同目标。
//send text from Content Box 1 to Master Box 1
protected void btnContentButton1_Click(object sender, EventArgs e)
{
//use one of the options below
//option 1. use master page public property
Master.PropertyMasterTextBox1.Text = txtContentBox1.Text;
//option 2. alternativly, call Master page public method
//to assign a value to the control on master page
Master.SetMasterBox1Value(txtContentBox1.Text);
}
btnContentButton2
的点击事件处理程序从Master Box 2(蓝色)检索文本并将其显示在Content Box 2(栗色)中。请看下面的代码列表。
//Get text from Master Box 2 and display it in Content Box 2
protected void btnContentButton2_Click(object sender, EventArgs e)
{
////use one of the options below
//option 1. access master page's TextBox through
//a public property exposed on mater page
txtContentBox2.Text = Master.PropertyMasterTextBox2.Text;
//option 2. Call master page public method
txtContentBox2.Text = Master.GetMasterBox2Value();
//option 3. use FindControl() method of Master object
txtContentBox2.Text = ((TextBox)Master.FindControl("txtMasterBox2")).Text;
}
除了调用母版页属性或方法的选项1和选项2之外,还有一个选项可用,即Master
对象的FindControl()
方法。请注意,此方法直接在母版页上搜索本地服务器控件。因此,在使用时无需公开公共属性或方法。通过此方法找到的服务器控件必须被强制转换为正确的类型。在上面的选项3中,找到了服务器控件txtMasterBox2
,并将其强制转换为TextBox
类型。
母版页与内容页交互
要使母版页与内容页进行交互,需要将母版页上服务器控件的事件连接到内容页。还应在内容页上实现相应的事件处理程序。
在我们的示例应用程序中,利用btnMasterButton1
和btnMasterButton2
的公共属性PropertyMasterButton1
和PropertyMasterButton2
来处理它们的点击事件。相应的事件处理程序是PropertyMasterButton1_Click()
和PropertyMasterButton2_Click()
。从下面的代码列表中可以看到,事件连接代码放置在Page_Init
事件处理程序中。这是因为事件必须在每次回发时触发。将其留在Page_Init
中比放在Page_Load
中更清晰,以避免处理Page_Load
中PostBack()
逻辑的复杂性。
//raise button click events on content page for the buttons on master page
protected void Page_Init(object sender, EventArgs e)
{
Master.PropertyMasterButton1.Click += new EventHandler(PropertyMasterButton1_Click);
Master.PropertyMasterButton2.Click += new EventHandler(PropertyMasterButton2_Click);
}
//Send text from Master Box 1 to Content Box 1
protected void PropertyMasterButton1_Click(object sender, EventArgs e)
{
//use one of the options below
//option 1. use master page public property
txtContentBox1.Text = Master.PropertyMasterTextBox1.Text;
//option 2. Call master page method
txtContentBox1.Text = Master.GetMasterbox1Value();
//option 3. use FindControl() method of Master object
txtContentBox1.Text = ((TextBox)Master.FindControl("txtMasterBox1")).Text;
}
//Get text from Content Box 2 to Master Box 2
protected void PropertyMasterButton2_Click(object sender, EventArgs e)
{
//use one of the options below
//option 1. User master page's property
Master.PropertyMasterTextBox2.Text = txtContentBox2.Text;
//option 2. call master page's method
Master.SetMasterBox2Value(txtContentBox2.Text);
}
事件处理程序PropertyMasterbutton1_Click()
将数据从母版页发送到内容页,而处理程序PropertyMasterButton2_Click()
则将数据从内容页检索到母版页。同样,有多种选项可供选择,无论是通过访问公共属性,调用母版页的公共方法,还是利用前面部分解释的FindControl()
方法。
结论
通过一点点编程工作,内容页和母版页就可以根据需要进行交互。本文提供的演示应用程序在内容页和母版页之间进行简单的数据交换。由于公开了公共属性和方法,并且将母版页上服务器控件的事件连接到了内容页,因此可以轻松实现更复杂的交互。尽管本文仅涉及TextBox
和Button
服务器控件,但其他类型的控件也可以以相同的方式进行处理。