0

我正在尝试编写一个方法来动态加载给定页面的控件集合,以便我可以遍历它并创建驻留在页面上的某些类型的控件的列表。这个想法是,对于从特定页面类继承的任何页面,我想编译一个具有某些属性的可编辑字段列表。这一切都发生在这些页面之外(在允许用户管理这些其他页面的不同页面上)。

我尝试了以下两种情况:

BasePage page = (BasePage)System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(string.Format("~/Pages/{0}/Manage.aspx", type.ToString()), typeof(BasePage));

IHttpHandler handler = PageParser.GetCompiledPageInstance(string.Format("~/Pages/{0}/Manage.aspx", type.ToString()), Context.Server.MapPath(string.Format("~/Pages/{0}/Manage.aspx", type.ToString())), HttpContext.Current);
BasePage page = handler as BasePage;

在这两种情况下,页面变量都已启动,但控件集合为空白,可能是因为这两种方法都只加载代码隐藏而不是标记。如何动态加载页面的控件集合?

4

3 回答 3

0

我不会弄乱页面生命周期。让 ASP.NET 自己管理控件层次结构,并使用一些递归逻辑来检查页面上的控件:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        FindPanelControls(Page);
    }
}

private void FindPanelControls(Control ctrl)
{
    if (ctrl.HasControls())
    {
        foreach (var childCtrl in ctrl.Controls.OfType<WebControl>())
        {
            //check for certain attributes
            if (childCtrl is Panel)
                Response.Write(childCtrl.ID);

            //recursively call the function for this control
            FindPanelControls(childCtrl);
        }
    }
}
于 2012-04-04T21:32:41.957 回答
0

你把它复杂化了;只需递归遍历 Page.Controls 集合并检查您感兴趣的控件类型。看看这些较早的问题:

ASP.Net / C#,循环浏览页面上的某些控件?

循环访问 asp.net 网页上的所有控件

于 2012-04-04T21:32:54.297 回答
0

我遇到了完全相同的要求,即需要在运行时从页面 B 评估页面 A 的控件。

在页面的整个生命周期中运行页面还需要一个额外的步骤。我们只需要调用 Page.ProcessRequest() 方法。Page.ProcessRequest 方法 (MSDN)。该方法对 Intellisense 隐藏。

在此之后,您将能够访问页面中的控件:

Page page = (Page)BuildManager.CreateInstanceFromVirtualPath("~/MyPage.aspx", typeof(Page));
page.ProcessRequest(HttpContext.Current);

如果您的页面有母版页,您将需要深入了解母版页的占位符。

请务必注意微软的言论:

“你不应该调用这个方法。”

“此 API 支持 .NET Framework 基础结构,不打算直接从您的代码中使用。

我还不知道这样做是否有任何不利影响。


编辑:在一个页面中执行一个页面会导致无数的问题,所以我朝一个稍微不同的方向走。

使用HTML Agility Pack,我们可以很容易地加载 *.aspx 文件并递归遍历其节点。如果我们想查找页面上的所有 asp 按钮,例如:

private static void FindAllButtonControls(HtmlNodeCollection htmlNodeCollection, List<HtmlNode> controlNodes)
{
    foreach (HtmlNode childNode in htmlNodeCollection)
    {
        if (childNode.Name.Equals("asp:button"))
        {
            controlNodes.Add(childNode);
        }
        else
        {
            FindAllButtonControls(childNode.ChildNodes, controlNodes);
        }
    }
}

public static List<HtmlNode> FindButtonControlsAtVirtualPath(String path)
{
    HtmlAgilityPack.HtmlDocument aspx = new HtmlAgilityPack.HtmlDocument();

    aspx.OptionFixNestedTags = true;
    aspx.Load(HttpContext.Current.Server.MapPath(path));

    List<HtmlNode> controlNodes = new List<HtmlNode>();
    FindAllButtonControls(aspx.DocumentNode.ChildNodes, controlNodes);

    return controlNodes;
}
于 2013-10-16T05:33:33.340 回答