簡體   English   中英

如何在 ASP.NET 中按類而不是 ID 選擇元素?

[英]How to select an element by Class instead of ID in ASP.NET?

我在 aspx 頁面上有一些分散的<p>元素,我使用這樣的類將它們組合在一起 - <p class="instructions" runat="server">

在我后面的代碼中,使用 C# 我想隱藏這些元素,使用諸如instructions.Visible = false;類的東西instructions.Visible = false;

但是我意識到如果我使用 ID,我只能在代碼隱藏中執行此操作,但這將導致無效的 HTML/CSS 選擇器,因為您不能有多個 ID 具有相同的 ID 名稱...

或者,如果不是按類,是否還有另一種方法可以對控件進行分組?

編輯:我不能使用 JavaScript,所以選擇必須在 C# 代碼隱藏/ASP.NET 中完成

事情很簡單。 在您的 ASPX 中:

<p class="instructions" runat="server" OnPreRender="Paragraph_PreRender">

在您的代碼隱藏中:

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

代碼隱藏將自動連接到類中的 PreRender 事件處理程序。 這會將發送者強制轉換為控件並根據 css 類設置其可見性。 您只需要調整標簽,並且不需要大量代碼來遍歷您的控件集合。

除了在單個容器控件中對所有控件進行分組之外,沒有簡單的方法可以在 ASP.NET 服務器端代碼中找到給定某些屬性的一組控件。

在客戶端,您可以使用類似jQuery 的東西來查找這些元素並隱藏它們:

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

當頁面完全加載時,我可能會這樣做:

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

在 Javascript 中隱藏元素的一個缺點是,如果有足夠的數據,它可能需要一秒鍾並導致內容閃爍。 另一個區別是客戶端隱藏內容不會將其從 DOM 中刪除 - 內容只是隱藏在那里。 在服務器端隱藏控件可以防止它們的內容被發送到 HTML。

在 C# 中做同樣的事情有點困難 - 它需要遞歸遍歷控件樹並在Control集合中查找匹配的元素。 這是一個足夠常見的操作,效用函數很有用。C# 迭代器語法(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" );

現在隱藏控件相對容易:

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

我想回應第一個答案 - 我們使用遞歸來完成所有控件。 首先,我們不應該對子項進行遞歸嗎? 我沒有仔細查看代碼,發現我們一直在“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;
    }

請注意,我不能使用“CssClass”——我必須使用我自己的屬性('ishidden')來讓它工作。

<div runat="server" ishidden="1"> ... </div>

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

如果您包含 JQuery 核心,您所要做的就是在您的頁面上注冊此腳本:

<script>
 $(document).ready(function() {
    $(".instructions").hide();
 });
</script>

它使用 JQuery 類選擇器http://api.jquery.com/class-selector/

您可以創建一個遞歸函數來遍歷頁面控件數組,檢查每個控件的 CssClass 屬性並根據需要進行設置。

<asp:Panel>方法

如果它們連續放置在您的表單中,您可以將它們全部放入 an 中。 這樣您就可以輕松切換面板的 .Visible 屬性以隱藏表單的塊。

JavaScript 方法

您可以使用ClientScriptManager.RegisterStartupScript()發出 JavaScript,然后使用 jQuery 按類隱藏。

建立在 Sebastian 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中:

 <asp:Label ID="Label1" CssClass="instructions" runat="server" Text="Label" onPreRender="Paragraph_PreRender"></asp:Label>

我已經測試了 blackcatweb 的解決方案。 它返回重復項,因此我修復了它並為 WebControl 添加了方法。 我的代碼如下。 要按類設置 attrName="class" 進行搜索:

    /// <summary>
    /// Find controls
    /// </summary>
    /// <param name="c">Control</param>
    /// <param name="predicate">Function</param>
    /// <returns>Control's</returns>
    public static IEnumerable<Control> FindRecursive(Control c, Func<Control, bool> predicate)
    {
        if (predicate(c))
        {
            yield return c;
        }

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

    /// <summary>
    /// Find WebControls by attr
    /// </summary>
    /// <param name="c">Control</param>
    /// <returns>WebControls</returns>
    public static IEnumerable<WebControl> 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;
        }
    }

    /// <summary>
    /// Find HtmlGenericControls by attr
    /// </summary>
    /// <param name="c">Control</param>
    /// <returns>HtmlGenericControls</returns>
    public static IEnumerable<HtmlGenericControl> 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 的控件。 遍歷這些控件並相應地設置它們的顯示屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM