9

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

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

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

4

5 回答 5

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);
}
于 2013-08-20T21:54:05.717 回答
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))
        {
            // ...
        }
    }
}
于 2013-08-20T21:46:23.970 回答
1

这似乎已经改变,因为我在 4.5 中看到,HasControls当 中只有文字文本Content,甚至是单个空格时,确实返回 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。

于 2016-02-25T00:00:00.843 回答
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,因为它们将我的网页中的插槽传递到下一个母版页或实际页面。

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

最后:

if (ChildrenCount(MyContentPlaceholder) == 0)
    MyContentPlaceholder.Controls.Add(new LiteralControl("My default content!"));
于 2016-04-25T20:35:08.417 回答
-1

我的 2 美分:

如果它是一个不变的内容,你必须插入并且根本没有<Content>

<asp:ContentPlaceHolder>
   <!-- Anything here will be inserted if there's no Content -->
</asp:ContentPlaceHolder>
于 2013-08-20T22:31:20.803 回答