c# - error using FindControl on div id

39,684

If your page is using a MasterPage, the div control will not be in the main collection of controls. That collection only contains the Content controls pointing to the ContentPlaceholder of your MasterPage.

There are three options:

  1. Use FindControl on the Content control: contentControl.FindControl("button1");
  2. Do a recursive FindControl until you find the control you need
  3. Normally, a declaration of your div control is added to your designer.cs codebehind, so you can directly access the control by its name: button1.Attributes["class"] = "classNameHere";

Update

I have created a MasterPage, added a Content Page to it, and added <div id="button1" runat="server">Some text</div> to the Content Page.

In the codebehind of my Content Page, I added this code:

protected void Page_Load(object sender, EventArgs e)
{
    var control = FindHtmlControlByIdInControl(this, "button1");

    if (control != null)
    {
        control.Attributes["class"] = "someCssClass";
    }
}

private HtmlControl FindHtmlControlByIdInControl(Control control, string id)
{
    foreach (Control childControl in control.Controls)
    {
        if (childControl.ID != null && childControl.ID.Equals(id, StringComparison.OrdinalIgnoreCase) && childControl is HtmlControl)
        {
            return (HtmlControl)childControl;
        }

        if (childControl.HasControls())
        {
            HtmlControl result = FindHtmlControlByIdInControl(childControl, id);
            if (result != null) return result;
        }
    }

    return null;
}

This works for me.

Share:
39,684
JasonH
Author by

JasonH

Updated on August 03, 2022

Comments

  • JasonH
    JasonH almost 2 years

    I have an ASP.NET site that I am trying to access div elements by their ID from the C# code behind file. Essentially I want to see if a div element exists, and if so, alter its properties.

    I've found many resources out there that point to a dozen different solutions and none of them seem to work.

    HTML on ASP.Net Page:

    <div class="contentArea">
         <div class="block" id="button1" runat="server">
                Some Content Here
         </div>
         <div class="block" id="button2" runat="server">
                Some Content Here
         </div>
         <div class="block" id="button3" runat="server">
                Some Content Here
         </div>
    </div>
    

    C# Code Behind (examples I've tried):

    System.Web.UI.HtmlControls.HtmlGenericControl div1 = (System.Web.UI.HtmlControls.HtmlGenericControl)this.FindControl("button1");
    div1.Attributes["class"] = "classNameHere";
    

    or

    Control div1 = this.FindControl("button1");
    div1.GetType();
    

    When the code gets to the second line of each of the above examples, I get an error:

    Object reference not set to an instance of an object.

    If I try the following:

    if (div1 != null)
    {
        // Do Something;
    }
    

    Nothing ever happens because div1 is always set to null. Ironically, if I look at the Locals window and examine this, I can see the button# ids in the listing, so I know they are there, but the system is acting like it isn't finding the control.

    My ultimate goal is to find the max id # of the button divs (looking at my html example, the max id would be 3 (button3). Maybe there is a better way to go about it, but either way, once I have my max id, I want to be able to touch each div and alter some css properties.

    Although I could easily do all of this via jQuery, in this instance I need to do this in C#.

    Any help is much appreciated. If you need more info, let me know.

    UPDATE I created a new C# web project from scratch. After adding a masterpage (and not altering it) and adding a webform using masterpage, I only added one line to the webform under Content ID="Content2":

    <div id="button1"></div>
    

    From c# code behind I still run into the same exact issue as before.

    FINAL UPDATE AND ANSWER I'm shocked no one (including myself) caught my mistake from the above update. I never put runat="server" when I created a new project from scratch under the div. Here is how I fixed my problem under my new project from scratch:

    Add runat="server" to div:

    <div id="button1" runat="server"></div>
    

    Then I did a FindControl on the ContentPlaceHolder under the MasterPage:

    ContentPlaceHolder myPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
    

    Note: This is what the ContentPlaceHolder code looks like on the Site.Master page created by default:

    <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
    
    </asp:ContentPlaceHolder>
    

    After finding this ContentPlaceHolder in code behind, I then searched within this placeholder for button1:

    using System.Web.UI.HtmlControls;
    HtmlControl myControl = (HtmlControl)myPlaceHolder.FindControl("button1");
    

    Finally I check to see if myControl is null:

    if (myControl != null)
    {
        \\ Do Something
    }
    

    When I ran this code, it found the div I was looking for. Here is the complete code behind all put together:

    using System.Web.UI.HtmlControls;
    
    ContentPlaceHolder myPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
    HtmlControl myControl = (HtmlControl)myPlaceHolder.FindControl("button1");
    
    if (myControl != null)
    {
        // Do Something
    }