在3.5框架中使用服务器标记<%= %>设置可见属性

60

我一直在一个.NET Framework 4项目中工作,使用服务器标签(如<%=whatever %>)来设置runat="server"控件的可见性,就像下面这样:

  <div id="MyId" runat="server" visible="<%=MyVisiblePropertyOnCodeBehind %>" >
    Content
  </div>

这在框架4上有效,但现在尝试在框架3.5项目中使用它似乎不起作用。这是仅适用于Framework 4的功能吗?是否有更酷的(并且.aspx端)替代方案来从codebehind设置可见性?我正在使用丑陋的:

    MiId.Visible = MyVisiblePropertyOnCodeBehind

[编辑] 解决方案:

感谢你的评论,让我理解了我的问题和解决方案!

问题出在我犯了多个错误。

我们在VS2010项目中使用了<%#而不是<%=。

此外,我没有注意到在VS2010项目中,我们使用的页面不是继承自“Page”,而是继承自CustomPage类,该类可以自动进行绑定,而我没有注意到这一点,这使我认为这是一个只有Framework 4.0才有的功能。

正如您在此处所述,如果您具有以下标记:

  <div id="MyId" runat="server" visible="<%# MyVisiblePropertyOnCodeBehind %>" >
    Content
  </div>

你可以让它工作,只需在代码后台添加以下内容:

    public bool  MyVisiblePropertyOnCodeBehind = true;
    protected void Page_Load(object sender, EventArgs e) {
        DataBind();
        // Or if you want only for one control, MyId.DataBind();             
    }

据我所知,使用DataBind()可能会降低应用程序的性能。你有没有想法这可能会造成多少影响?它是否可以被理解为一种适用于大型项目的“专业技术”,还是应该避免使用?

我喜欢它使标记在一个视图中易读易懂的方式,但我不希望因此而导致代码运行缓慢。


"你的 'MyVisiblePropertyOnCodeBehind' 属性的签名是什么?" - PraveenVenu
实际上,我不认为在代码后台设置它很丑陋。如果您希望提醒控件可能不可见,请在代码前端将“visible=‘false’”设置为默认值。 - crenshaw-dev
5个回答

82

您贴出的代码在ASP.NET 2.0或ASP.NET 4.0运行时中不是有效的服务器标记语法。在任一版本中,尝试使用<%= ... %>在服务器标记中设置可见属性应导致解析器错误:

解析器错误消息:无法从其字符串表示形式“<%=MyVisiblePropertyOnCodeBehind%>”创建类型为'System.Boolean'的对象,用于“Visible”属性。

除了在代码后端或<script runat="server">标记中设置Visible属性之外,您还有两个选择。第一个是在Visible属性上使用数据绑定。您需要在MyId或其父控件之一上调用DataBind()方法才能绑定该值。

<div id="MyId" runat="server" visible="<%# MyVisiblePropertyOnCodeBehind %>" >
    Content
</div>

另一种选择是按照以下方式编写代码:

<% if(MyVisiblePropertyOnCodeBehind) { %>
<div id="MyId" runat="server">
    Content
</div>
<% } %>
这种方法的缺点是您无法以编程方式向页面或包含代码块的控件添加控件。 如果尝试这样做,应该会出现错误:
“Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)”。
话虽如此,我认为按照您现在所做的方式设置属性是正确的方法。

我终于通过这个,以及“arunes”信息中的链接理解了我的问题。谢谢。(抱歉,我是新手,无法投票。) - tomasofen
1
@rsbarro 我发现在使用<% if块时还有另一个奇怪的问题,即在回传时会抛出验证错误。如果该块包含一个不应呈现的RequiredFieldValidator,则回传仍将使用它并导致验证失败。我发现我仍然需要使用布尔表达式来设置Enabled='<%# false %>'并在代码后台Page_Load中调用someControlId.DataBind();以使验证器在回传时被禁用。 - AaronLS
在用户控件的代码后台中调用this.DataBind();并使其适用于列表视图和数据网格是否可行?就像在OnInit方法中一样? - Roar

3
关于ASP.NET aspx页面的内联表达式。 <% %> 只能在aspx页面或用户控件的顶级文档级别中使用,但不能嵌入到服务器控件的标签属性中(例如<asp:Button... Text =<% %> ..>)。正如您所发现的,您可以在ASP.NET 2.0中创建自定义表达式生成器以添加内联表达式。
顺便说一下,在aspx内联模板中为服务器控件属性提供值的另一种方法是使用<%# %>数据绑定表达式。这是内置支持的。与其他内联表达式唯一不同的是目标控件或其容器控件上的方法。
Steven Cheng
Microsoft MSDN在线支持负责人
完整帖子在此处:http://www.aspnet-answers.com/microsoft/ASP-NET/29389067/dynamically-set-a-control-property.aspx

这里有一个解决方案:ASP.net内联表达式问题


2

只需在页面加载事件中设置一个变量为true/false,像这样:

private bool IsEditMode {get; set;}      

protected bool IsVisible 
{
    get { retun IsEditMode ;}
    set { IsEditMode =value;}
}  

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        // based on some condition set this to true or false 
        isEditMode=true;
    }
}   

然后在您的aspx页面中的控件属性中,通过类似于以下的属性设置它们的可见性

Visible="<%# !IsEditMode %>" 

抱歉,但我认为这与问题无关,而且代码很混乱,属性名称也不同 :( - tomasofen
@tomasofen 我已经使用适当的命名更新了我的答案。 - Zo Has

2
这里有另一种方法,保持了你原始问题中代码的简单性。在这里,您需要从div标签中删除runat="server"并使用css "display:none"代替"Visible"属性。这种方法的缺点是,即使它不可见并且可见性在客户端处理,标记仍然会发送到浏览器。
<div style='<%=MyVisiblePropertyOnCodeBehind ? "" : "display: none" %>' >
    Content
</div>

0
另一种方法是给控件分配一个ID,并在代码中设置可见性。
protected void Page_Load(object sender, EventArgs e){
   MyId.Visible = MyVisiblePropertyOnCodeBehind;
} 

<div id="MyId" runat="server">Content</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接