2010-09-07 60 views
1

我需要一個母版的ContentPlaceHolders的名單,但物業如何在代碼隱藏中獲取MasterPage的ContentPlaceHolders列表?

protected internal IList ContentPlaceHolders { get; } 

是內部保護的,所以我們不能訪問它們。

有什麼辦法可以將它們從MasterPage(包括Reflection)中拉出來?謝謝。

+0

不要忘記,以紀念自己喜歡的答案。 – Steven 2010-11-21 16:43:50

回答

2

如果你不介意使用反射並且不介意你的應用打破遷移到.NET的新版本時的風險,這將工作:

IList placeholderNames = 
    typeof(MasterPage).GetProperty("ContentPlaceHolders", 
     BindingFlags.Instance | BindingFlags.NonPublic) 
    .GetValue(myMasterPage, null) as IList; 
+0

感謝您的警告。 =) – Jronny 2010-09-08 00:57:13

2

你可以通過主環路遞歸。控制並檢查每個控件是否屬於ContentPlaceHolder類型。

private readonly IList<ContentPlaceHolder> _contentPlaceHolders = new List<ContentPlaceHolder>(); 
private void FindContentPlaceHolders(ControlCollection controls) 
{ 
    foreach(Control control in controls) 
    { 
     if (control is ContentPlaceHolder) 
     { 
      _contentPlaceHolders.Add((ContentPlaceHolder) control); 
      return; 
     } 
     FindContentPlaceHolders(control.Controls);    
    } 
} 
+0

雖然這比反思風險小。也許Master.Controls.Cast ()。其中​​(a => a是ContentPlaceHolder) 。選擇(a =>(ContentPlaceHolder)a)也可以。 =) – Jronny 2010-09-08 00:52:06

+0

我試過了,但我非常不幸它不起作用。 =( – Jronny 2010-09-08 03:38:56

+0

我測試了一箇舊的webforms項目(.NET 3.5)與兩個ContentPlaceHolders的母版頁,它爲我工作,我將Master.Controls傳遞到FindContentPlaceHolders方法中,我注意到ContentPlaceHolders沒有直接包含在Master.Controls集合,它們在層次結構中進一步嵌套。 – 2010-09-08 06:23:03

1

至於丹尼爾回答的變化,你可以寫,作爲一個擴展方法上MasterPage

public static IEnumerable<ContentPlaceHolder> 
    GetContentPlaceHolders(this MasterPage master) 
{ 
    return GetAllControlsInHierarchy(master) 
     .OfType<ContentPlaceHolder>(); 
} 

private static IEnumerable<Control> GetAllControlsInHierarchy(
    Control control) 
{ 
    foreach (var childControl in control.Controls) 
    { 
     yield return childControl; 

     foreach (var childControl in 
      GetAllControlsInHierarchy(childCOntrol)) 
     { 
      yield return childControl; 
     } 
    } 
}