在母版页中查找ContentPlaceHolders

时间:2010-09-24 15:09:00

标签: c# asp.net master-pages

我正在寻找一种动态加载母版页的方法,以便在其中获取ContentPlaceHolders的集合。

在我可以访问它的控件之前,我宁愿不必加载页面对象来分配母版页,但如果这是我将乐意使用它的唯一方法。这是我希望它能起作用的方式:

        Page page = new Page();
        page.MasterPageFile = "~/home.master";
        foreach (Control control in page.Master.Controls)
        {
            if (control.GetType() == typeof(ContentPlaceHolder))
            {
                // add placeholder id to collection
            }
        }

page.Master抛出空引用异常。在页面生命周期中创建实际页面时,它似乎只在某个时刻加载。

我甚至想过在Page_Init()上动态更改当前页面的MasterPageFile,读取所有ContentPlaceHolders然后再分配原始MasterPageFile,但那太可怕了!

有没有办法将主页面加载到独立于实际页面的内存中,以便我可以访问它的属性?

我的最后手段可能涉及解析ContentPlaceHolders的母版页内容,这不是很优雅,但可能会更快一些。

有人能帮忙吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

您应该能够使用LoadControl加载母版页以枚举Controls集合。

  var site1Master = LoadControl("Site1.Master");

要查找内容控件,您需要递归搜索Controls集合。这是一个快速而又肮脏的例子。

static class WebHelper
{
  public static IList<T> FindControlsByType<T>(Control root) 
    where T : Control
  {
    List<T> controls = new List<T>();
    FindControlsByType<T>(root, controls);
    return controls;
  }

  private static void FindControlsByType<T>(Control root, IList<T> controls)
    where T : Control
  {
    foreach (Control control in root.Controls)
    {
      if (control is T)
      {
        controls.Add(control as T);
      }
      if (control.Controls.Count > 0)
      {
        FindControlsByType<T>(control, controls);
      }
    }
  }
}

以上可以使用如下

  // Load the Master Page
  var site1Master = LoadControl("Site1.Master");

  // Find the list of ContentPlaceHolder controls
  var controls = WebHelper.FindControlsByType<ContentPlaceHolder>(site1Master);

  // Do something with each control that was found
  foreach (var control in controls)
  {
    Response.Write(control.ClientID);
    Response.Write("<br />");
  }