如何检查ContentPlaceHolder是否为空?

时间:2013-08-20 21:43:51

标签: c# asp.net

如何检查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>

我需要做的是当占位符为空时,将默认内容放在另一个控件中。

覆盖为同一个占位符尝试了两次,但在动态加载时出现错误。

5 个答案:

答案 0 :(得分:5)

您可以实现一个将内容控件呈现为字符串的方法,然后检查字符串以查找包含任何非空白字符的字符:

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);
}

答案 1 :(得分: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))
        {
            // ...
        }
    }
}

答案 2 :(得分: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;
}

对于我来说,我将直接放入Content元素的文本将由OfType作为具有适当内容的LiteralControl返回。不仅如此,我的格式(“\ r \ n \ t”)也将以相同的方式返回。当我们将网页中的插槽传递到下一个母版页或实际页面时,我还会为后续母版页获取ContentPlaceholders。

因此,现在的任务是获取排除这些ContentPlaceholder的控件计数,并且还排除空格的LiteralControls。使用运算符非常简单。我们只是确保给定的控件既不是那些类型,然后计算它,或者如果它是Literal我们检查内容是否都是空白。最后一步是以递归方式为所有子ContentPlaceholder添加相同操作的结果,以便嵌套的母版页按预期工作。

最后:

if (ChildrenCount(MyContentPlaceholder) == 0)
    MyContentPlaceholder.Controls.Add(new LiteralControl("My default content!"));

答案 3 :(得分:0)

这似乎已经改变,因为我在4.5中看到 HasControlsContent 中只有文字文本时,即使是一个空格,也会返回true。我在我的母版页中做了类似的事情:

<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">内呈现侧边栏内容(如果有的话),并避免在没有内容时在页面上创建空div。

答案 4 :(得分:-1)

我的2美分:

如果它是一个恒定的内容,你将不得不插入AND,根本不会有<Content>

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