How to add element inside ListItem in code behind? - c#

I want to add something like this in the code behind:
<ul>
<li><a>A</a></li>
</ul>
However, the ListItem of ASP.NET seems to allow text only:
BulletedList UserSubMenuList = new BulletedList();
ListItem EditUserItem = new ListItem("Edit Profile");
Is there other way to add content between <li></li> tag with code behind rather then using HtmlGenericControl?

Front :
<ul id="test" runat="server">
</ul>
Back:
Label label1=new Label();
label1="test";
test.Controls.Add(new LiteralControl("<li>"));
test.Controls.Add(label1);
test.Controls.Add(new LiteralControl("</li>"))

Try this:
BulletedList UserSubMenuList = new BulletedList();
UserSubMenuList.Items.Add(new ListItem(HttpUtility.HtmlEncode(#"Edit Profile"));
Note that you'll be clearing whatever was initially displayed if you do the first line (the constructor).
The Text property is simply the string of text to put in the <li> tags - if it's text (like all HTML markup), it should be able to go there.

Related

find control not able to find controls that created with literal control

this is MyFirstRow in my .aspx file:
<ul class="dropdown-menu" id="MyFirstRow" runat="server">
I created the control with this Code in CodeBehind :
Control Con = FindControl("MyFirstRow");
LiteralControl LCx = new LiteralControl();
LCx.Text = #"<li class='dropdown' id='MyFirstRow34' runat='server'>
<a href='#'>Sample<span class='caret'></span></a></li>";
Con.Controls.Add(LCx);
so far everything is ok, but after next line when I use this code, this not able to find any control In the event that this added Correctly:
Con = FindControl("MyFirstRow34");
where is my mistake?
tnx for your response.
Edited :
My question is how to access this control with id=MyFirstRow34 in Code-Behind?
The <li class='dropdown' id='MyFirstRow34' runat='server'> string content assigned to the LiteralControl doesn't get interpreted by ASP.NET; this string is only part of the html output.
In order to find the control by the given Id, you must assign the Id to the controls ID property, as shown below.
LiteralControl LCx = new LiteralControl { ID = "MyFirstRow34" };
The full code of your example will look like this:
Control Con = FindControl("MyFirstRow");
LiteralControl LCx = new LiteralControl { ID = "MyFirstRow34" };
LCx.Text = #"
<li class='dropdown'>
<a href='#'>Sample<span class='caret'></span></a>
</li>";
Con.Controls.Add(LCx);
Control myFirstRow34 = FindControl("MyFirstRow34");

How to get input element from Literal

On the sever side, I've created, a literal with text set to an input type file element with runat = 'server' property, mode set to passThrough and append it to a div. Both the literal and input element have it's own unique id. My issue is trying to get that input element from the div tag. I'm able to get the literal programmatically, but the literal doesn't contain any controls and text value has the input element I need. I tried looking for the input element o it's own and keep getting null. I've inspected the page and I see the input element with runat='server'and it's and yet I can't get it. I need to be able to get this input element in order to upload it's file.
This is what I've tried so far:
Client-Side:
<div runat="server" id="docRequeridosMainDiv" style="display: table;
width: 60%; text-align: right">
<%-- Control set on server side --%>
</div>
Server-Side: (Testing this on pageload event)
//Attach inivisible input type file
uploadLit.Text += string.Format(#"<div><input type='file' id='{0}File' runat = 'server' style='display: none;'
onchange='" + docsRequeridos.ElementAt(i).Nombre + #"FileSelected()' /></div>", lbl.Text);
uploadLit.ID = lbl.Text + "FileLit";
docRequeridosMainDiv.Controls.Add(uploadLit);
//var lit = (Literal)docRequeridosMainDiv.FindControl(uploadLit.ID);
var lit = (HtmlGenericControl)docRequeridosMainDiv.FindControl(lbl.Text +"File");
Ignore the event attached to input, that works.
I've debugged the commented lit and on the controls collection has 0 but the text has the input. The second lit is returns a null value.
Tried getting it with the same Findcontrol line on a click event and still same result. Literal with no controls.
Just in case you're wondering why the input is display:none cause I'm doing a custom file upload, but that's not important cause every other functionality works, the only on that doesn't work is this one.
FindControl() will find only server controls. Adding html control (with runat="server" as string) into a Literal will not make those controls servier-side. But you can use HtmlInputFile to achieve the same, like this:
var fileInput = new HtmlFileInput
{
ID = lbl.Text + "File"
};
fileInput.Attributes["onchange"] = docsRequeridos.ElementAt(i).Nombre + "FileSelected()";
fileInput.Attributes["style"] = "display:none";
docRequeridosMainDiv.Controls.Add(fileInput);
Now, you can find this control like:
var foundFileInput = docRequeridosMainDiv.FindControl(lbl.Text +"File") as HtmlFileInput;
If you want to wrap this file input with div, you need to make another HtmlGenericControl and add that fileInput to that; like this:
var myDiv = new HtmlGenericControl("div")
{
ID = "FileUploadContainer"
};
myDiv.Controls.Add(fileInput);
docRequeridosMainDiv.Controls.Add(myDiv); // Add myDiv instead of fileInput
This will generate exactly the html you wanted, but just programmatically (not with Literal string), and controls are now server-side.

how to change some labels in ASP.Net page by for loop form code behind?

I have 10 Label control in an ASP.Net page. their Id are in row like label1, label2, label3, ... ,label10 I want to change their Text property to something like
Home1 , Home2, Home3, ... Home10 Can I do this from code behind by using For loop or something like that?
Suppose your labels are inside a div tag (don't forget to add runat="server"):
<div id="labels" runat="server">
<%--Your Labels--%>
</div>
And in the code behind:
int i = 1;
foreach (var item in labels.Controls)
{
if (item is Label)
{
((Label)item).Text = "Home" + i;
i++;
}
}

Tabs in WebForms

I'm trying to create a set of tabs at runtime and they were, for a time, working correctly- however now they just seem to display the contents of all tabs underneath the previously rendered tab. As silly as it seems, as far as I can tell, in terms of code nothing has changed since the code was working so I am a little confused as to what is going on...
For the purpose of this example I will not use a loop, although this seems irrespective as the loop doesn't appear to be the problem.
<asp:Panel runat="server" ID="pnlTabs">
<ul runat="server" id="ulSections" />
</asp:Panel>
I've come to the conclusion that my code must be at fault so here is the C#:
HtmlGenericControl liTab = new HtmlGenericControl("li");
HtmlGenericControl anTab = new HtmlGenericControl("a");
anTab.Attributes.Add("href", "#Tab1");
anTab.InnerText = Tab1;
liTab.Controls.Add(anTab);
ulSections.Controls.Add(liTab);
var pnl = new Panel();
pnl.ID = Tab1;
pnlTabs.Controls.Add(pnl);
I place my controls and what not on the "pnl". Can anyone please tell me what my mistake is?
//THIS ADDS THE <A> to the <LI>
liTab.Controls.Add(anTab);
//THIS ADDS THE <LI> to the <UL>
ulSections.Controls.Add(liTab);
//THIS CODE Appear to have nothing to do with anything.
var pnl = new Panel();
pnl.ID = Tab1;
pnlTabs.Controls.Add(pnl);
Can you confirm if the HTML is even being rendered in the html when you View Source.
Where in your code behind is this code... in a button click, on Page Load, On Init ?
I discovered what the problem was, it was basically that the InnerText of "anTab" cannot be the same as the href attribute of "anTab" as this causes confusion and results in the content from all tabs to appear only in the first (selected) tab, while the remaining tabs don't function.
For example, the following code works correctly as the InnerText of "anTab" is "Tab 1" and the href is looking for a control with the ID "Tab1", which is the ID of the panel.
HtmlGenericControl liTab = new HtmlGenericControl("li");
HtmlGenericControl anTab = new HtmlGenericControl("a");
anTab.Attributes.Add("href", "#Tab1");
anTab.InnerText = "Tab 1";
liTab.Controls.Add(anTab);
ulSections.Controls.Add(liTab);
var pnl = new Panel();
pnl.ID = "Tab1";
pnlTabs.Controls.Add(pnl);
Below we can see that the InnerText of "anTab" is the same as the href and the ID of the panel we wish to use as the tab, this causes the confusion as the href now assumes you want the "tab click" to point to itself instead of the actual panel.
HtmlGenericControl liTab = new HtmlGenericControl("li");
HtmlGenericControl anTab = new HtmlGenericControl("a");
anTab.Attributes.Add("href", "#Tab1");
anTab.InnerText = "Tab1";
liTab.Controls.Add(anTab);
ulSections.Controls.Add(liTab);
var pnl = new Panel();
pnl.ID = "Tab1";
pnlTabs.Controls.Add(pnl);

C# - How to change HTML elements attributes

My master page contains a list as shown here. What I'd like to do though, is add the "class=active" attribute to the list li thats currently active but I have no idea how to do this. I know that the code goes in the aspx page's page_load event, but no idea how to access the li I need to add the attribute. Please enlighten me. Many thanks.
<div id="menu">
<ul id="nav">
<li class="forcePadding"><img src="css/site-style-images/menu_corner_right.jpg" /></li>
<li id="screenshots">Screenshots</li>
<li id="future">Future</li>
<li id="news">News</li>
<li id="download">Download</li>
<li id="home">Home</li>
<li class="forcePadding"><img src="css/site-style-images/menu_corner_left.jpg" /></li>
</ul>
</div>
In order to access these controls from the server-side, you need to make them runat="server"
<ul id="nav" runat="server">
<li class="forcePadding"><img src="css/site-style-images/menu_corner_right.jpg" /></li>
<li id="screenshots">Screenshots</li>
<li id="future">Future</li>
<li id="news">News</li>
<li id="download">Download</li>
<li id="home">Home</li>
<li class="forcePadding"><img src="css/site-style-images/menu_corner_left.jpg" /></li>
</ul>
in the code-behind:
foreach(Control ctrl in nav.controls)
{
if(!ctrl is HtmlAnchor)
{
string url = ((HtmlAnchor)ctrl).Href;
if(url == GetCurrentPage()) // <-- you'd need to write that
ctrl.Parent.Attributes.Add("class", "active");
}
}
The code below can be used to find a named control anywhere within the control hierarchy:
public static Control FindControlRecursive(Control rootControl, string id)
{
if (rootControl != null)
{
if (rootControl.ID == id)
{
return rootControl;
}
for (int i = 0; i < rootControl.Controls.Count; i++)
{
Control child;
if ((child = FindControlRecursive(rootControl.Controls[i], id)) != null)
{
return child;
}
}
}
return null;
}
So you could do something like:
Control foundControl= FindControlRecursive(Page.Master, "theIdOfTheControlYouWantToFind");
((HtmlControl)foundControl).Attributes.Add("class", "active");
Forgot to mention previously, that you do need runat="server" on any control you want to be able to find in this way =)
Add runat="server" on the li tags in the masterpage then add this to the appropriate page_load event to add the 'active' class to the li in the masterpage
HtmlGenericControl li = HtmlGenericControl)Page.Master.FindControl("screenshots");
li.Attributes.Add("class", "active");
You could register a client script like this:
(set id to the id of the li that you want to set to active)
ClientScript.RegisterStartupScript(this.GetType(), "setActiveLI", "document.getElementById(\""+id+"\").setAttribute(\"class\", \"active\");", true);
This generates a JavaScript call on the page near the bottom after elements have already been rendered.
All the parts have already been provided in previous answers, but to put the whole thing together, you'll need to:
add the runat="server" attribute to the <ul> and <li> elements
add a public method to do the work on the master page that can be called from the pages using the master page
call the method from the Page_Load of the pages
Alternatively you could also add the code to the OnLoad(...) method of the master page, so you don't have to add the method call to the Page_Load on every page.
If they were runat=server you could use the attributes property.
In order to find that particular control it will need to be defined as public (in the generated designer)
Or will need to be wrapped by a public get in the codebehind.
You can expose the li's on the master page to any content pages by wrapping them in properties on the master page:
public GenericHtmlControl Li1
{
get
{
return this.LiWhatever;
}
}
Then on the content page:
MasterPage2 asd = ((MasterPage2)Page.Master).Li1.Attributes.Add("class", "bla");
If i've got that right!
I found a link that works using CSS and involves only changing the body tag's class attribute. This means there's no Javascript and there's no for loops or anything.
#navbar a:hover,
.articles #navbar #articles a,
.topics #navbar #topics a,
.about #navbar #about a,
.contact #navbar #contact a,
.contribute #navbar #contribute a,
.feed #navbar #feed a {
background: url(/pix/navbarlinkbg.gif) top left repeat-x; color: #555;
}
....
<body class="articles" onload="">
<ul id="navbar">
<li id="articles">Articles</li>
<li id="topics">Topics</li>
<li id="about">About</li>
<li id="contact">Contact</li>
<li id="contribute">Contribute</li>
<li id="feed">Feed</li>
</ul>
Read more here
http://www.websiteoptimization.com/speed/tweak/current/
Try this
the great example for future use. i know this thread is old, but for future queries...
http://community.discountasp.net/showthread.php?p=33271
Thanks For the solution.
Mininized code.
Master page control can also find in the child page..
i mean master page contains html contol
and chilld page can find the master page html conrol like this
((HtmlControl)this.Master.FindControl("dpohome1")).Attributes.Add("class", "on");
Simple logic and minimal code, I usually use the following code, especially in dynamic menu. Hope this helps.
Create this method code in the code behind master page
CODE BEHIND (C#)
protected string SetCssClass(string page)
{
return Request.Url.AbsolutePath.ToLower().EndsWith(page.ToLower()) ? "active" : "";
}
In the menu list items you have created call this method passing the page name like this
HTML PAGE (ASPX inline code)
<li id="screenshots" class = "<%= SetCssClass("screenshots.aspx") %>">
Screenshots</li>
<li id="future" class = "<%= SetCssClass("future.aspx") %>">
Future</li>
and so on.
By this method, every time you add a page and link, you don't have to write code in every page. Just when you add the link in the master page, with every <li> invoke the SetCssClass(pagename) method call for setting class and it's done. (you can rename the method as per your ease.
You can use longer codes if you are being paid per lines of code bcoz then this is just one line of code. (lol). Just kidding. Hope it helps.
Note: I am ignoring other parts of the html code, you can include them also, that would work fine.

Categories

Resources