Найти ContentPlaceHolders на главной странице - PullRequest
3 голосов
/ 24 сентября 2010

Я ищу способ динамической загрузки главной страницы, чтобы получить коллекцию 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 выдает исключение нулевой ссылки. Кажется, он загружается только в какой-то момент, когда в жизненном цикле страницы создана настоящая страница.

Я даже думал о динамическом изменении MasterPageFile текущей страницы в Page_Init (), чтении всех ContentPlaceHolders и назначении исходного MasterPageFile обратно, но это было бы ужасно!

Есть ли способ загрузить главную страницу в память независимо от реальной страницы, чтобы я мог получить доступ к ее свойствам?

Мое окончательное решение, вероятно, будет включать в себя анализ содержимого главной страницы для ContentPlaceHolders, что не так элегантно, но может быть немного быстрее.

Кто-нибудь может помочь, пожалуйста? Большое спасибо.

1 Ответ

1 голос
/ 24 сентября 2010

Вы должны иметь возможность использовать LoadControl для загрузки главной страницы и перечисления коллекции элементов управления.

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

Чтобы найти элементы управления содержимым, вам потребуется рекурсивный поиск в коллекции элементов управления.Вот быстрый и грязный пример.

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 />");
  }
...