使用动态多态从内容页面访问嵌套主控页上的控件






2.09/5 (3投票s)
如何使用动态多态从内容页面访问嵌套母版页上的控件,而无需强制转换为母版页类。
引言
本文解释了如何使用单个方法查找任意数量层级的母版页上的控件,而无需类型转换或使用 Master.Master
。这里使用的概念是通过重写 FindControls()
方法来实现动态多态。
背景
在某些情况下,您可能只是在应用程序中添加了对母版页的嵌套,并且一些控件已被移动到超级母版页。所有使用 Page.master
调用的 FindControl
方法都会中断,并且您现在必须使用 Page.Master.master
加上类型转换。我设计了一种方法,这样任何代码都不会受到影响。您只需要做的是向新创建的母版页文件添加一些代码。我发现拥有一个查找控件的单个方法,通过扫描内容页面上方的母版页层次结构非常有用。
使用代码
我在这里尝试使用动态多态。众所周知,每个 Page
类或母版页类都有一个内置的 FindControl
方法,用于查找该页面中的控件。为了使 FindControls
方法可以在层次结构的任何位置查找控件,我只需执行以下操作。
假设我们有两层嵌套
BaseMasterPage.master
,代码隐藏 BaseMasterPage.master.csSubMasterPage.master
,代码隐藏 SubMasterPage.master.cs,母版页:BaseMasterPage.master
- MyPage.aspx,代码隐藏 MyPage.aspx.cs,母版页:
SubMasterPage.master
设置好上述层次结构后,创建一个名为 SuperBaseMaster.cs 的超级基类。
public class SuperBaseMaster : MasterPage
{
}
如以下代码片段所示,重写 SuperBaseMaster.cs 中的 FindControl
方法。我还在递归方法中使用,以在基本母版页中查找控件。
注意:为此,所有母版页代码隐藏类都必须派生自一个公共的超级基类,该基类派生自 MasterPage
,如上所示
public Control BaseFindControl(string id)
{
return base.FindControl(id);
}
public override Control FindControl(string id)
{
return FindMyControl(id, this);
}
private Control FindMyControl(string id, BaseMasterPage master)
{
//If currentmaster is null, then the control with "id" is not found
//so return null
if (master == null) return null;
//Call the inbuilt base FindControl
Control ctl = master.BaseFindControl(id);
if (ctl == null)
{
//Call the FindMyControl method recursively
return FindMyControl(id, (BaseMasterPage)master.Master);
}
return ctl;
}
在上面的代码中,BaseFindControl
执行原始 FindControl
方法过去所做的事情。由于我们已经重写了 FindControl
,我们需要某种方式来访问原始方法。因此,有了这个方法。
接下来,重写的 FindControl
将调用我们的递归方法 FindMyControl
。
FindMyControl
将首先尝试在当前母版页(作为参数传递)上查找控件。如果找不到控件,则它会使用下一个更高级别的母版页 (master.Master
) 再次调用自身,直到找到该控件。如果找不到,最后将返回 null
。
到目前为止一切顺利。
如果您已经阅读到这里,那么让我们看看如何调用我们重写的 FindControl
方法。为此,假设我们想找到一个 ID 为“myTextBoxID
”的文本框控件。并且,此控件存在于 BaseMasterPage
上。以下是代码
<body> <form id="form1" runat="server">
<div>
<asp:TextBox ID="myTextBoxID" runat="server"></asp:TextBox>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder> </div>
</form></body>
要以传统方式从内容页面中找到此文本框控件,您将执行以下操作
SubMasterPage subMaster = (SubMasterPage)this.Page.Master;
BaseMasterPage baseMaster = (BaseMasterPage)subMaster.Master;
TextBox mytextBox = (TextBox)baseMaster.FindControl("myTextBoxID");
现在,使用我们的动态方法,您将执行以下操作
TextBox myTextBox = (TextBox)this.Page.Master.FindControl("myTextBoxID");
就是这样。一行代码。对于任何级别的层次结构,它都只是一行代码。并且,不需要类型转换(尽管还有其他避免类型转换的方法,但我不会深入讨论这些细节)。
这里的主要点是,这将充当母版页的通用方法,并且您不必担心控件在层次结构中上下移动(当母版页被重构时,这种情况经常发生)。
希望这对于那些使用重构嵌套母版页的人有所帮助。欢迎评论。