2010-09-24 15 views
3

我正在尋找一種方法來動態加載母版頁,以獲得ContentPlaceHolders中的一個集合。在母版頁中查找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

您應該能夠使用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 />"); 
    } 
+0

優秀的,這正是我試圖做的,在一個更優雅的方式。謝謝! – 2010-09-24 17:02:48

+0

@GarryM,我花了一些時間,稍微清理一下代碼。 – 2010-09-24 21:44:37