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

我在aspx页面上有一些分散的

元素,我使用类似的类将它们组合在一起 –

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

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

或者是否有其他方法来分组控件,如果不是按类?

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

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

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

 $(".instructions").hide(); 

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

 $(document).ready(function() { $(".instructions").hide(); }); 

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

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

 // utility method to recursively find controls matching a predicate IEnumerable FindRecursive( Control c, Func 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" ); 

现在隐藏控件相对容易:

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

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

 

在你的代码隐藏中:

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

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

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

编辑后,我有这个:

  // utility method to recursively find controls matching a predicate IEnumerable FindRecursive( Control c, Func 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; } 

请注意,我无法使用“CssClass” – 我必须使用自己的属性(’ishidden’)来实现此function。

 
...

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

如果您包含JQuery核心,您只需在页面上注册此脚本:

  

它使用JQuery类选择器http://api.jquery.com/class-selector/

您可以创建一个递归函数来遍历页面控件数组,检查每个控件的CssClass属性并根据需要进行设置。

方法

如果它们连续放在您的表单中,您可以将它们全部放入其中。 这样,您可以轻松切换面板的.Visible属性以隐藏表单的块。

JavaScript方法

您可以使用ClientScriptManager.RegisterStartupScript()发出JavaScript,然后使用jQuery按类隐藏。

我测试了blackcatweb的解决方案。 它返回dublicates,所以我修复了它并为WebControls添加了方法。 我的代码如下。 要按类set attrName =“class”进行搜索:

  ///  /// Find controls ///  /// Control /// Function /// Control's public static IEnumerable FindRecursive(Control c, Func predicate) { if (predicate(c)) { yield return c; } foreach (Control child in c.Controls) { foreach (Control founded in FindRecursive(child, predicate)) { yield return founded; } } } ///  /// Find WebControls by attr ///  /// Control /// WebControls public static IEnumerable FindWebControlsByAttr(Control baseControl, string attrName, string attrValue) { foreach (WebControl c in FindRecursive(baseControl, c => (c is WebControl) && !string.IsNullOrEmpty(((WebControl)c).Attributes[attrName]) && ((WebControl)c).Attributes[attrName].Contains(attrValue))) { yield return c; } } ///  /// Find HtmlGenericControls by attr ///  /// Control /// HtmlGenericControls public static IEnumerable FindControlsByAttr(Control baseControl, string attrName, string attrValue) { foreach (HtmlGenericControl c in FindRecursive(baseControl, c => (c is HtmlGenericControl) && !string.IsNullOrEmpty(((HtmlGenericControl)c).Attributes[attrName]) && ((HtmlGenericControl)c).Attributes[attrName].Contains(attrValue))) { yield return c; } } 

您可以使用JQuery类名称选择器来实现此目的。
另一个解决方案是保持相同的id而不是控制服务器端。 在JavaScript中使用document.getElementById获取控件,在您的情况下,您将获得一个数组,该数组将保存具有相同ID的所有控件。 迭代这些控件并相应地设置其显示属性。

在塞巴斯蒂安PR Gingter解决方案的基础上,这就是我所做的,虽然考虑到我必须使用基于MS的WebControl而不是选择更简单的HTML控件,它仍然感觉有点黑客。

在C#中:

 protected void Paragraph_PreRender(object sender, EventArgs e) { WebControl paragraph = (WebControl)sender; paragraph.Visible = !paragraph.CssClass.Contains("instructions"); } 

在aspx中: