65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.09/5 (3投票s)

2007年10月30日

CPOL

3分钟阅读

viewsIcon

46500

如何使用动态多态从内容页面访问嵌套母版页上的控件,而无需强制转换为母版页类。

引言

本文解释了如何使用单个方法查找任意数量层级的母版页上的控件,而无需类型转换或使用 Master.Master。这里使用的概念是通过重写 FindControls() 方法来实现动态多态。

背景

在某些情况下,您可能只是在应用程序中添加了对母版页的嵌套,并且一些控件已被移动到超级母版页。所有使用 Page.master 调用的 FindControl 方法都会中断,并且您现在必须使用 Page.Master.master 加上类型转换。我设计了一种方法,这样任何代码都不会受到影响。您只需要做的是向新创建的母版页文件添加一些代码。我发现拥有一个查找控件的单个方法,通过扫描内容页面上方的母版页层次结构非常有用。

使用代码

我在这里尝试使用动态多态。众所周知,每个 Page 类或母版页类都有一个内置的 FindControl 方法,用于查找该页面中的控件。为了使 FindControls 方法可以在层次结构的任何位置查找控件,我只需执行以下操作。

假设我们有两层嵌套

  1. BaseMasterPage.master,代码隐藏 BaseMasterPage.master.cs
  2. SubMasterPage.master,代码隐藏 SubMasterPage.master.cs,母版页:BaseMasterPage.master
  3. 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");

就是这样。一行代码。对于任何级别的层次结构,它都只是一行代码。并且,不需要类型转换(尽管还有其他避免类型转换的方法,但我不会深入讨论这些细节)。

这里的主要点是,这将充当母版页的通用方法,并且您不必担心控件在层次结构中上下移动(当母版页被重构时,这种情况经常发生)。

希望这对于那些使用重构嵌套母版页的人有所帮助。欢迎评论。

© . All rights reserved.