2013-08-20 11 views
5

ContentPlaceHolderが完全に空であるかどうかを確認するには?ContentPlaceHolderが空であるかどうかを確認するには?

ContentPlaceHolderには、タグとコントロールのないテキストのみがあります。

例Page.Master:

<asp:ContentPlaceHolder runat="server" ID="Content" /> 

例Test.aspxという:

<asp:Content runat="server" ContentPlaceHolderID="Content"> 
    Custom text without controls. Content.Controls.Count is 0 and Content.HasControls is false. 
</asp:Content> 

私が行う必要がある何がプレースホルダーが空に置かれたとき、デフォルトのコンテンツが別のコントロールであるということです。

同じプレースホルダに対して上書きが2回試みられましたが、動的読み込み時にエラーが発生します。

+0

何を達成しようとしているの? – Patrick

答えて

4

あなたはそれがどんな非が含まれていwheahter検索した文字列をチェックし、文字列にコンテンツコントロールを描画するメソッドを実装することができます・ホワイトスペース文字:

private bool HasContent(Control ctrl) 
{ 
    var sb = new System.Text.StringBuilder(); 
    using (var sw = new System.IO.StringWriter(sb)) 
    { 
     using(var tw = new HtmlTextWriter(sw)) 
     { 
      ctrl.RenderControl(tw); 
     } 
    } 

    var output = sb.ToString().Trim(); 

    return !String.IsNullOrEmpty(output); 
} 

protected void Page_PreRender(object sender, EventArgs e) 
{ 
    var placeholder = Master.FindControl("FeaturedContent"); 
    var hasContent = HasContent(placeholder); 
} 
+0

Controls.Countは0ですが、テキストがあります。空ではありません。 –

+0

申し訳ありませんが、テンプレート化されたサーバーコントロールは、マークアップを.aspxページからサーバーコントロールに変換しません。あなたが使用できるアプローチの1つを使って答えを更新しました。文字列ビルダーでコンテンツコントロールをレンダリングし、空白文字がないかどうかを確認します。 – defrost

+0

非常に非常に非常に感謝:) –

1

最初にマスターページでContentPLaceHolderを見つける必要があります。次に、常に存在する最初のコントロールをLiteralControlにキャストし、それをTextプロパティに使用します。

コンテンツ・ページのPage_Loadから期待されるように、これは動作します:

protected void Page_Load(object sender, EventArgs e) 
{ 
    var cph = Page.Master.FindControl("Content") as ContentPlaceHolder; 
    if (contentPlaceHolder != null) 
    { 
     string textualContent = ((LiteralControl) cph.Controls[0]).Text; 
     if (string.IsNullOrEmpty(textualContent)) 
     { 
      // ... 
     } 
    } 
} 
+0

Visual Studioは言う:ArgumentOutOfRangeException。私のコードです:文字列textualContent =((LiteralControl)CustomHeader.Controls [0])。 \t \t \t(string.IsNullOrEmpty(textualContent)) \t \t \t { \t \t \t \t/* CargaラカベセラPOR defecto */ \t \t \t \tユーザーコントロールヘッド=(ユーザーコントロール)Page.LoadControl( "〜/もしレイアウト/テーマ/ "+ config.themeSelected +" /header.ascx "); \t \t \t \t CustomHeader.Controls.Add(head); \t \t \t} –

+0

@WHK:私は自分の答えを編集しました。 –

+0

同じ問題、文字列を破るtextualContent =((LiteralControl)cph.Controls [0])。同じエラーが発生しました。内容が上になると、Lacoleccióndeは制御されたポケベルを制御していない状態になります(<% ... %>)。 –

-1

私の2セント:

それはあなたが挿入する必要があります一定のコンテンツだとNOは存在しません場合全く:

<asp:ContentPlaceHolder> 
    <!-- Anything here will be inserted if there's no Content --> 
</asp:ContentPlaceHolder> 
+0

使用しないでください。 –

+0

私はあなたのコメントを理解していません。 – ispiro

+0

なぜdownvote?私はその質問がこのような事件を含めるのに十分な広さだったと思う。 – ispiro

0

これは私がContentで唯一のリテラル・テキスト、1つでも空白がある場合にtrueを返しDOES HasControlsことを4.5に見ていますので、変更されているようです。 - と何のコンテンツがありませんときにページ上の空のdivを作成避け

<asp:Panel id="SidebarPanel" CssClass="Sidebar" runat="server"> 
    <asp:ContentPlaceHolder id="SidebarContent" runat="server" /> 
</asp:Panel> 

Sub Page_Load(...) 
    SidebarPanel.Visible = SidebarContent.HasControls 
End Sub 

これは、任意の<div class="Sidebar">の内側に、存在する場合には、サイドバーのコンテンツをレンダリングする:私は私のマスターページでは、このような何かを行います。

1

レンダリング後に変化する状態を持つコントロールがあるかもしれないレンダリングやリスクのために、すべてのコードを実行することは本当にありませんでした。だから私は別のアプローチを思いついた。

public static int ChildrenCount(ContentPlaceHolder placeholder) 
{ 
    int total = 0; 
    total += placeholder.Controls.OfType<Control>().Where(x => 
     (!(x is ContentPlaceHolder) && !(x is LiteralControl)) || 
     (x is LiteralControl && !string.IsNullOrWhiteSpace(((LiteralControl)x).Text)) 
    ).Count(); 
    foreach (var child in placeholder.Controls.OfType<ContentPlaceHolder>()) 
     total += ChildrenCount(child); 
    return total; 
} 

私にとって、コンテンツ要素に直接配置するテキストは、適切な内容のLiteralControlとしてOfTypeによって返されます。これだけでなく、書式設定( "\ r \ n \ t")も同じ方法で返されます。私はまた、次のマスターページや実際のページに自分のWebページのスロットを通過すると、ContentPlaceholdersを取得します。

これで、これらのContentPlaceholdersを除外し、空白であるLiteralControlsも除外したコントロールの数を取得することができます。これは、オペレータであることを使用するとかなり簡単です。与えられたコントロールがこれらの型でないことを確かめ、それを数えるか、リテラルであれば内容がすべて空白かどうかを調べます。最後のステップは、ネストされたマスターページが期待通りに機能するように、すべての子ContentPlaceholderに対して同じ操作の結果を再帰的に追加することです。

そして最後に:

if (ChildrenCount(MyContentPlaceholder) == 0) 
    MyContentPlaceholder.Controls.Add(new LiteralControl("My default content!")); 
関連する問題