如何在ASP.NET中按类而不是ID选择元素?

fir*_*ger 17 c# asp.net select selection css-selectors

<p>在aspx页面上有一些分散的元素,我使用类似的类将它组合在一起 -<p class="instructions" runat="server">

在我的代码背后,使用C#我想隐藏这些元素,使用类似的东西 instructions.Visible = false;

但是我知道如果我使用ID,我只能在代码隐藏中执行此操作,但这会导致无效的HTML/CSS选择器,因为您不能拥有具有相同ID名称的多个ID ...

或者是否有另一种方法来分组控件,如果不是按类?

编辑:我不能使用JavaScript,因此选择必须在C#codebehind/ASP.NET中完成

Seb*_*ter 19

事情很简单.在你的ASPX中:

<p class="instructions" runat="server" OnPreRender="Paragraph_PreRender">
Run Code Online (Sandbox Code Playgroud)

在你的代码隐藏中:

protected void Paragraph_PreRender(object sender; EventArgs e)
{
  Control paragraph = (Control)sender;
  paragraph.Visible = !paragraph.CssClass.Contains("instructions");
}
Run Code Online (Sandbox Code Playgroud)

代码隐藏将自动连接到类中的PreRender事件处理程序.这会将发件人强制转换为控件,并根据css类设置其Visibility.您只需调整标记,就不需要遍历控件集合的大量代码.


LBu*_*kin 14

除了在单个容器控件中对所有控件进行分组之外,在ASP.NET服务器端代码中给定一些属性没有简单的方法来查找一组控件.

在客户端,您可以使用类似jQuery的东西来查找这些元素并隐藏它们:

$(".instructions").hide();
Run Code Online (Sandbox Code Playgroud)

我可能会在页面完全加载时执行此操作:

$(document).ready(function() { 
   $(".instructions").hide(); 
});
Run Code Online (Sandbox Code Playgroud)

在Javascript中隐藏元素的一个缺点是,如果有足够的数据,它可能需要一秒钟,并导致内容闪烁.另一个区别是隐藏内容客户端不会将其从DOM中删除 - 内容只是隐藏.隐藏控件服务器端可防止其内容被发送到HTML.

在C#中做同样的事情有点困难 - 它需要递归遍历控制树并查找Control集合中匹配的元素.这是一个很常见的操作,实用程序功能很有用.C#iterator语法(yield return)有助于使其干净:

// utility method to recursively find controls matching a predicate
IEnumerable<Control> FindRecursive( Control c, Func<Control,bool> predicate )
{
    if( predicate( c ) )
        yield return c;

    foreach( var child in c.Controls )
    {
        if( predicate( c ) )
            yield return c;
    }

    foreach( var child in c.Controls )
        foreach( var match in FindRecursive( c, predicate ) )
           yield return match;
}

// use the utility method to find matching controls...
FindRecursive( Page, c => (c is WebControl) && 
                          ((WebControl)c).CssClass == "instructions" );
Run Code Online (Sandbox Code Playgroud)

现在隐藏控件相对容易:

foreach( WebControl c in FindRecursive( Page, c => (c is WebControl) && 
                           ((WebControl)c).CssClass == "instructions" ) )
{
    c.Visible = false;
}
Run Code Online (Sandbox Code Playgroud)


bla*_*web 5

我想回答第一个答案之一 - 我们使用递归来完成所有控件.首先,我们不应该对儿童用品进行递归吗?我没有仔细查看代码,发现我们一直在"c"上递归调用该方法,而不是"child".其次,我发现我的网页上没有任何项目可以转换为WebControl - 仅限于HtmlGenericControl.

编辑后,我有这个:

    // utility method to recursively find controls matching a predicate
    IEnumerable<Control> FindRecursive( Control c, Func<Control,bool> predicate )
    {
        if( predicate( c ) )
            yield return c;

        foreach (var child in c.Controls) {
            if (predicate((Control)child)) {
               yield return (Control)child;
            }
        }

        foreach( var child in c.Controls )
            foreach( var match in FindRecursive( (Control)child, predicate ) )
               yield return match;
    }

    foreach (Control c in FindRecursive(Page, c => (c is HtmlGenericControl) &&
         ((HtmlGenericControl)c).Attributes["ishidden"] == "1"))
    {
         c.Visible = false;
    }
Run Code Online (Sandbox Code Playgroud)

请注意,我无法使用"CssClass" - 我必须使用自己的属性('ishidden')来实现此功能.

<div runat="server" ishidden="1"> ... </div>
Run Code Online (Sandbox Code Playgroud)

我正在使用ASP.NET framework 2.0/3.0/3.5.