动态编译页面并访问其控件

ASP.NET中,有时可能需要从不同的页面控制另一个页面。这种方法的一个主要问题是服务器会在内存中加载请求的页面。因此,在同一时间,只能处于一个页面,比如Page1。可以在Page1中创建Page2的对象,但是无法获取关于控件的信息,因为只有在Page_Init触发时控件才会初始化,而只是创建了页面的对象,并没有涉及生命周期。

为了解决这个问题,.NET提供了许多类,这些类有助于动态编译页面,并且非常有用,如果想缓存页面以实现更快的访问和更好的用户体验。应该了解ASP.NET页面是在用户请求时编译并缓存以供后续使用的。

将讨论并使用的类是BuildManager类。让从Page1中计算Page2中的Panel控件数量。将使用反射来动态创建实例,这就是为什么需要页面的类型信息。这可以通过以下方式实现:

// 获取引用路径的编译类型 string pagePath = "~/Page2.aspx"; Type type = BuildManager.GetCompiledType(pagePath);

一旦有了类型,就可以继续使用以下方式创建Page2的实例:

Page myPage = (Page)Activator.CreateInstance(type);

上面的代码将创建页面实例,但如果尝试访问Page2的Controls集合,会发现它为0,这是因为只是调用了构造函数来创建实例。没有涉及页面生命周期,这是填充页面控件所必需的。要执行页面生命周期,将调用Page类上的ProcessRequest方法,如下所示:

myPage.ProcessRequest(HttpContext.Current);

现在可以访问控件集合并做想做的事情。

以下是计算页面中Panel数量的完整代码:

// 初始化计数为0 int count = 0; // 获取引用路径的编译类型 string pagePath = "~/Page2.aspx"; Type type = BuildManager.GetCompiledType(pagePath); // 如果类型为null,则无法确定页面类型 if (type == null) throw new ApplicationException("Page " + pagePath + " not found"); Page myPage = (Page)Activator.CreateInstance(type); myPage.ProcessRequest(HttpContext.Current); foreach (Control control in myPage.Controls) { if (control is Panel) ++count; if (control.HasControls()) CountControls(control, ref count); } private static void CountControls(System.Web.UI.Control control, ref int count) { foreach (System.Web.UI.Control childControl in control.Controls) { System.Web.UI.WebControls.WebControl webControl = childControl as System.Web.UI.WebControls.WebControl; if (webControl != null) { if (webControl is System.Web.UI.WebControls.Panel) ++count; if (webControl.HasControls()) CountControls(webControl, ref count); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485