c# - error using FindControl on div id - c#

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
}

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:
Use FindControl on the Content control: contentControl.FindControl("button1");
Do a recursive FindControl until you find the control you need
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.

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.

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

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?

Related

Access HTML Inputs on Postback in ASP.NET

I've struggled with this for days now, trying to access html inputs, i.e. checkboxes or textboxex generated at runtime based on DB results. My HTML which is added as a literal control to a asp placeholder looks like this:
<div class='cart-item'>
<div class='product-name'> <h3>gold baseball figure</h3></div>
<img src='Graphics/gold-trophy.png'></img>
<div class='inventory-short-description'> <p>A finely crafted gold plated baseball figuring to top your choice of trophey base (sold seperatly).</p></div>
<div class='clear'></div>
<div class='item-price'><p>$22.95</p></div>
<div class='cart-item-checkbox'><label><input type='checkbox' id='1' name='1' runat='server'/> Select </label>
<a href='products.aspx?viewItem=1'>view item </a></div></div
Question is, how do I access this check box in the .cs code behind page?
My code which is generating this html and adding it to the page is in the overrided OnInit method. Looking at the placeholder on postback shows that the checkbox is in the literal control.
I've tried:
Page.FindControl() returns null when searching for dynamic control
ASP.NET page_init event?
FindControl() return null
http://forums.asp.net/t/1336244.aspx?finding+HTML+control
....And countless others.
Yesterday I used a hackish way to set the value of these checkboxes to a asp.net hidden field using jquery. My coworkers (all java devs) say this seems to be the wrong way to access these elements. Is there a better way? I'm beginning to think I've coded myself into a spot I can't get out of.
Thanks for the help.
In your .aspx
<asp:Repeater ID="rptItems" runat="server" EnableViewState="False">
<ItemTemplate>
<asp:TextBox ID="txtName" runat="server" />
</ItemTemplate>
</asp:Repeater>
In your .aspx.cs file you can access repeater in postback events as below
foreach (RepeaterItem rptItem in rptItems.Items)
{
TextBox txtName = (TextBox)rptItem.FindControl("txtName");
if (txtName != null) { System.Diagnostics.Debug.Write(txtName.Text); }
}

c# - codebehind div style change not being rendered

I have a div of the form
<div id="mydiv" runat="server" style="display:none"></div>
In my code behind, I attempt to change the display to block by
mydiv.Style["display"] = "block";
When I view the source code after the piece of code above is run, the page source reflects the change (i.e. the div's display is set to block) but the visible page does not. How can I get my page to show the div?
Where is your code mydiv.Style["display"] = "block";? I just test it in Page_Load,and in the view page,it displayed,and the code in page source is this
<div id="mydiv" style="display:block;">12345</div>
I set innerhtml to have a good view

How can I find div control of a repeater in C#?

I am using this div inside a repeater.
<div class="view" id="View">
I want this div control in asp.net c# code. This is my code now:
HtmlGenericControl h3name = null;
h3name = (HtmlGenericControl)RepeaterView2.Items[count].FindControl("View");
h3name.Style.Add("width", CHeight.ToString());
But I did not get the control. How can I solve this problem?
HtmlGenericControl defines the methods, properties, and events for all HTML server control elements not represented by a specific .NET Framework class.
So if its a server control you can simply use:
HtmlGenericControl sample= e.Item.FindControl("YOURDIVNAME") as HtmlGenericControl;
and also add runet="server" to your div.
First add a runat server in your div
<div class="view" id="View" runat="server">
now in item bound event of your repeater find it like
HtmlGenericControl sample= e.Item.FindControl("View") as HtmlGenericControl
Your div must be with runat = "server" attribute.

Clickable Webcontrol, ASP.NET

This is question is in relation to my last question in case you want some more background information.
My question is: Is it possible to make a cell in an asp.net Table clickable?
Or Is it at least possible to make a clickable WebControl (which should be possible to place in a ControlCollection), that is not a Button or a LinkButton, in ASP.NET?
And if not, is it possible to multiple lines of information into the button text?
I've tried adding other components to the button's ControlCollection (which I've seen working in the Windows Forms version of the Button), to see if I could render child components to a button, but without success:
private void ModifyTableCell(TableCell cell)
{
//Create new button
Button btnCell = new Button();
btnCell.Click += (sender, args) =>
{
//Event for the button
};
//Create new Label
Label lblCell = new Label();
lblCell.Font.Bold = true;
lblCell.Text = "This text won't appear";
btnCell.Controls.Add(lblCell); //Attempt to add label to Button
cell.Controls.Add(btnCell);
}
EDIT: I ended up just creating a multi-lined LinkButton for the entire cell.
You should be able to make pretty much any control clickable by assigning an onclick attribute and leveraging the __doPostBack function.
ctrl.Attributes["onclick"] = string.Format("__doPostBack('{0}', '{1}');", ctrl.ClientID, "SomeArgument");
You could also use the GetPostBackEventReference method too. This option is actually safer, because it will register the __doPostBack function it doesn't already exist:
ctrl.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(ctrl, string.Empty);
Then, in the code-behind you can simply override the RaisePostBackEvent method:
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
base.RaisePostBackEvent(source, eventArgument);
if (eventArgument == "SomeArgument") //using the argument
{
//do whatever
}
}
You can add multiple lines to a asp.net button by using the string builder, something like:
System.Text.StringBuilder buttonText = new System.Text.StringBuilder();
buttonText.AppendLine("first line");
buttonText.AppendLine("second line");
btnMultiline.Text = buttonText.ToString;
I am not sure how you imagine such a composite control would be rendered. Remember that each ASP.NET control in the end outputs HTML. You Button essentially outputs a
<input type="button">The button text</input>
If you want to place anything else inside the <input> tag, it must be HTML-compatible. I'm not sure the input tag allows other HTML inside.
If it is a LinkButton on the other hand, the generated HTML markup is an <a href=""> tag. You can put anything there, even an image if you wish, which will become clickable.
I am not sure what is your full scenario, but what you're trying to do smells bad. I suggest that you either use a LinkButton or rethink your approach, just have in mind what the final output in HTML would be.
In reading both of your posts, it looks like you want to be able to click on anything in the cell and have it post back as if the whole cell were a button?
If so, one of the fairly simple ways to do it is to build your cell content as you would if you were not trying to post back. Then add a button with a style of display:none;. You can then use client side scripting to capture the click event of the cell, and raise the click event of the button to cause a post back.
This allows you to create the cell content in any way you like, and the postback code and handlers are automatically generated for you.
Using JQuery you end up with something along the lines of this:
<head runat="server">
<style>
input.ClickableCellButton
{
display: none;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("td.ClickableCell").click(function (event) { $(event.target).children("input.ClickableCellButton").click() });
});
</script>
<div>
<table>
<tbody>
<tr>
<td class="ClickableCell">
Cell Contents<br />
on multiple lines
<asp:Button ID="Button1" runat="server" Text="Button" CssClass="ClickableCellButton"
OnClick="Button1_Click" />
</td>
</tr>
</tbody>
</table>
</div>
</form>
</body>
And if not, is it possible to multiple lines of information into the
button text?
For this particular case, you can accomplish this via CSS only; no need to extend Button:
<asp:button id="myMultilineButton" runat="server" style="width:60px; white-space: normal;" Text="Several lines of text" />
It will render as:

Controls in a telerik control not accessible from .cs file

I am using telerik controls in my c# asp.net project. I am trying to disable a div in a telerik navigation menu from the .cs file. For example:
if (Emp_Role == "1" || Emp_Role == "5")
{
DivLeave.Visible = true;
}
I try run the project I get this error:
CS0103: The name 'DivLeave' does not exist in the current context
Here is an example of the aspx code
<telerik:RadMenu runat="server" ID="RadMenu1" Skin="Sitefinity" OnClientItemOpened="itemOpened"
Width="670px" Height="26px" EnableShadows="true">
<Items>
<telerik:RadMenuItem Text="Expenses" PostBack="false">
<Items>
<telerik:RadMenuItem CssClass="Stores" Width="640px">
<ItemTemplate>
<div id="DivLeave" class="Wrapper">
<h3>
Expense Management</h3>
</div>
Can anyone help with this? If I place the div outside the telerik control it works fine. This is so frustrating!
Kind regards,
R
First, you have to use a asp.net control ( or at least a control that runs in server ) to be able to access it from code behind. For example.
<asp:Label ID="DivLeave" runat="server"></asp:Label>
Second, to get a control inside a Telerik control you need som special code. In your example, you can do something like this:
// Find menuitem by css class
RadMenuItem expenses = RadMenu1.FindItem(i => i.CssClass == "Stores");
// Find control inside menuitem
Label label = expenses.FindControl("DivLeave") as Label;
label.Visible = true;
To learn more:
Accessing Controls Inside Templates
Doing it client side will also work and you won't have to make the div become server side.
Using jQuery you can have:
if (Emp_Role == "1" || Emp_Role == "5")
{
Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "show_divleave", "$(function() { $(\"div[id$='DivLeave']\").each(function(index) { $(this).css(\"display\", \"\"); }); });", true);
}
This assumes those div elements are initially hidden using "display: none;" CSS rule.

Categories