如何检查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>
我需要做的是当占位符为空时,将默认内容放在另一个控件中。
覆盖为同一个占位符尝试了两次,但在动态加载时出现错误。
答案 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中看到 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。
答案 4 :(得分:-1)
我的2美分:
如果它是一个恒定的内容,你将不得不插入AND,根本不会有<Content>
:
<asp:ContentPlaceHolder>
<!-- Anything here will be inserted if there's no Content -->
</asp:ContentPlaceHolder>