加载页面';通过代码收集的控件
本文关键字:代码 控件 加载 | 更新日期: 2023-09-27 18:30:07
我正在尝试编写一个方法,该方法将动态加载给定页面的控件集合,以便我可以对其进行迭代,并创建驻留在页面上的某些类型控件的列表。其想法是,对于从特定页面类继承的任何页面,我都希望编译一个具有特定属性的可编辑字段列表。这一切都发生在这些页面之外(在另一个允许用户管理这些其他页面的页面上)。
我已经尝试了以下两种场景:
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;
在这两种情况下,都会启动页面变量,但控件集合为空,这可能是因为这两种方法都只加载代码绑定,而不加载标记。如何动态加载页面的控件集合?
我遇到了完全相同的要求,即需要在运行时从页面B评估页面a的控件。
在页面的整个生命周期中运行页面还需要一个额外的步骤。我们只需要调用Page.ProcessRequest()方法。Page.ProcessRequest方法(MSDN)。该方法对Intellisense隐藏。
在此之后,您将能够访问页面中的控件:
Page page = (Page)BuildManager.CreateInstanceFromVirtualPath("~/MyPage.aspx", typeof(Page));
page.ProcessRequest(HttpContext.Current);
如果你的页面有一个母版页,你需要深入了解母版页的占位符。
不过,一定要注意微软的评论:
"你不应该调用这个方法。"
"此API支持.NET Framework基础结构,并且不打算直接从代码中使用。"
我还不知道这样做是否会产生任何不利影响。
EDIT:在一个页面中执行一个页面可能会导致无数问题,所以我的方向略有不同。
使用HTML敏捷包,我们可以很容易地加载*.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;
}
我不会打乱页面生命周期。让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);
}
}
}
您过于复杂了;只需在Page.Controls集合中递归循环并检查您感兴趣的控件类型。看看前面的问题:
ASP.Net/C#,循环浏览页面上的某些控件?
循环浏览asp.net网页上的所有控件