8

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
}
12
  • 2
    FindControl works only for immediate descendant of current control (probably page). If the div is inside a panel typically, you will have to call findcontrol on the panel, or write a recursive method. Commented Jul 10, 2012 at 15:44
  • Your divs are ID'd bodyDiv1, bodyDiv2, bodyDiv3, but you are searching for a control with ID button1? Is there something you haven't included in the example code? Commented Jul 10, 2012 at 15:47
  • @Steve - The divs are not within any type of control. Commented Jul 10, 2012 at 15:52
  • @kaveman - I apologize, I grabbed the wrong section of HTML from my file, I updated the above. The only difference in what I gave you compared to what I have is there are more divs then what I provided. Commented Jul 10, 2012 at 15:53
  • 1
    Can you clarify how your HTML is being created? If that really is the HTML for the aspx page then I'm not sure why you cna't just accesson button1 directly without using findControl. I assume there is something more happening here though or it would be pointless... I assume that the divs are being generated dynamically on either the server or the client but it is very important to know which. If the client then you need to do somethign to tell the server about them or it won't know (and hence won't find them). So please include the code that is generating them if it exists... Commented Jul 10, 2012 at 15:56

4 Answers 4

11

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I've tried both 1 and 2 to no avail. #3 does not solve my issue, yes I can access them directly, but I need to be able to refer to the control name via a variable and I can't find anywhere how to do this other than a FindControl, which is ultimately failing me. So if you can tell me how I can essentially do: string button = "button" + i; and then call button.Attributes, then I can solve my problem in a different manor.
I have updated my answer with example code that works for me.
So when I created a new test site from scratch, I forgot to add runat=server to the div, so a lot of my testing yesterday went to waste. I tried your method and it worked, I also tried some other htings and it worked. Why it won't work yet on my normal project is another matter, but I can address that myself. Thanks!
Forgetting runat=server consume my hour too :D
1

If you add runat=server please add it at last of the div:

This will work

<div id="divBtn" class="mybuttonCass" runat="server">

However, this will not

<div runat="server" id="divBtn" class="mybuttonCass">

By doing that, you can modify any property from codebehind as:

divBtn.Style["display"] = "none";

This works even with masterpages. The div is not included in a masterpage.

Comments

0

You need to add a runat=server attribute to any control that you want to access in code behind. See this article for more help.

Accessing <div> from both javascript and code-behind

1 Comment

This is a very typical answer but is not the case here. As I stated when looking at the locals I can see the controls, and as Ruel stated, I have runat=server in my code already.
0

I cannot seem to be able to reproduce your problem, any chance your DIV's are within a template control such as UpdatePanel, Repeater, or Grid?

3 Comments

The divs are within an <asp:Content> control from within a MasterPage setup. Other than that, they are not within any type of template control as you suggested.
what about yourContentControl.FindControl("yourdiv") ?
Intellisense is not finding the Content control (and yes it has a unique ID and has runat=server).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.