Asp.net asp问题:内容占位符和代码块
当内容占位符包含任何代码块时,它会报告控件集合为空 例如: MasterPage.aspxAsp.net asp问题:内容占位符和代码块,asp.net,asp.net-mvc,master-pages,Asp.net,Asp.net Mvc,Master Pages,当内容占位符包含任何代码块时,它会报告控件集合为空 例如: MasterPage.aspx )但如果它包含任何控件,则无法将控件集合设置为空,因为当存在脚本标记时,文本控件不会添加到控件树中。但是,仍将添加服务器控件。因此: <asp:Content ID="Content2" ContentPlaceHolderID="Content2" Runat="Server"> <%= "Code block content." %> <asp:Gri
)但如果它包含任何控件,则无法将控件集合设置为空,因为当存在脚本标记时,文本控件不会添加到控件树中。但是,仍将添加服务器控件。因此:
<asp:Content ID="Content2" ContentPlaceHolderID="Content2" Runat="Server">
<%= "Code block content." %>
<asp:GridView runat="server" ID="gvTest" />
</asp:Content>
<div>Content2: <%= Content2.Controls.Count %></div>
:
要使这样的代码正常工作,请使用ASP.NET
需要重写的渲染
任何
脚本代码是托管的。它是通过
在上使用SetRenderMethodElegate
容器和创建自定义
渲染方法
而不是建立控制
树文字控件,仅限ASP.NET
将服务器控件添加到控件中
当标签存在于一个
容器。处理文字
内容和脚本标记,ASP.NET
生成自定义渲染方法。
然后,此方法显式写出
任何静态HTML内容和任何脚本
使用HTML文本编写器的表达式。
生成任何脚本代码()
作为方法本身的原始代码
不幸的是,对于这个难题,我想不出任何优雅的解决方案。正如我所承诺的,我说我会看看。对不起,我昨晚没上传,这是漫长的一天,我需要好好休息一下
因此,我检查了ContentPlaceHolder.Controls
集合在填充方式上的差异。我注意到,当使用代码块时,它会翻转为只读。在任何其他点,它都将是空的或填充的
因此,我决定加入一个扩展方法来为我们检查它:
ContentPlaceHolderExtensions.cs
然后在母版页中选中此项:
地点,主人
:
评论太多了,以下是我最终得到的完整代码(改编自@Rob Cooper的答案):
这包括两个额外的检查-首先检查空文本控件(如果页面包含很好的解释,就会出现这种情况。不过,这对MVC内容来说是一种痛苦-我不想为了让母版页可以看到内容面板被使用而将内容弄乱。必须有办法解决这个问题。感谢对上一个问题的评论-稍后从办公室回家后会查看此问题。。这一个让我很感兴趣!(+1来自我!)稍后将更新:)干杯(+1和acc)这是一个不错的选择。我做了一个调整-额外检查一个只包含空格的单个LiteralControl。打得好,我正在考虑自己添加:)谢谢!
<asp:Content ContentPlaceHolderID="Content1" runat="server">
Plain text content.
</asp:Content>
<asp:Content ContentPlaceHolderID="Content2" runat="server">
<%= "Code block content." %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Content2" Runat="Server">
<%= "Code block content." %>
<asp:GridView runat="server" ID="gvTest" />
</asp:Content>
<div>Content2: <%= Content2.Controls.Count %></div>
public static class ContentPlaceHolderExtensions
{
public static bool ContainsControlsOrCodeBlock(this ContentPlaceHolder placeHolder)
{
if (placeHolder.Controls.Count > 0)
return true;
return placeHolder.Controls.IsReadOnly;
}
}
<asp:ContentPlaceHolder ID="Content1" runat="server" />
<asp:ContentPlaceHolder ID="Content2" runat="server" />
<asp:ContentPlaceHolder ID="Content3" runat="server" />
<div>Content1: <%= Content1.Controls.Count %></div>
<div>Content2: <%= Content2.Controls.Count %></div>
<div>Content3: <%= Content3.Controls.Count %></div>
<div>Content1 (Ex. Meth.): <%= Content1.ContainsControlsOrCodeBlock() %></div>
<div>Content2 (Ex. Meth.): <%= Content2.ContainsControlsOrCodeBlock() %></div>
<div>Content3 (Ex. Meth.): <%= Content3.ContainsControlsOrCodeBlock() %></div>
<asp:Content ContentPlaceHolderID="Content1" runat="server">
Plain Text Content
</asp:Content>
<asp:Content ContentPlaceHolderID="Content2" runat="server">
<%= "Code block content" %>
</asp:Content>
public static bool HasContent( this ContentPlaceHolder placeHolder )
{
if ( placeHolder.Controls.Count > 0 )
{
LiteralControl textBlock;
ContentPlaceHolder subContent;
foreach ( var ctrl in placeHolder.Controls )
if ( (textBlock = ctrl as LiteralControl) != null )
{ //lit ctrls will hold any blocks of text
if ( textBlock.Text != null && textBlock.Text.Trim() != "" )
return true;
}
else if ( (subContent = ctrl as ContentPlaceHolder) != null )
{ //sub content controls should call this recursively
if ( subContent.HasContent() )
return true;
}
else return true; //any other control counts as content
//controls found, but all are empty
return false;
}
//if any code blocks are used the render mode will be different and no controls will
//be in the collection, however it will be read only
return placeHolder.Controls.IsReadOnly;
}