Render dynamic # of HTML controls in aspx page like #Razor? - c#

I know we can put a placehold on aspx page, then add controls dynamically from backend code. Is there a way in aspx page that is similar to #razor engine that we can add html control directly in aspx page?
<%
int count = GetImageCount();
for (int k = 0; k < count; k++)
{
string id = "img_" + k.ToString();
%>
<asp:Image runat="server" ImageAlign="Middle" />
<%
}
%>
We can use above code to add multiple Image control in aspx page, but how can we set them with different id and src?
Or, we can not do this in aspx directly?
thanks

You cannot set ID for server controls dynamically. Also, as far as I am aware of, setting ImageUrl direclty in aspx for the control in for loop, like in your code, might not be possible - you should probably take a look and asp:Repeater control.
To achieve what you want, you might find useful this piece of code, using HTML <img> control (as #Grundy suggested), instead of asp:Image control:
<% int count = 5;
for (int i = 0; i < count; i++)
{
string id = "id_" + i;
string imageUrl = "/Images/img_" + i;
%>
<img id="<%=id%>" src="<%=imageUrl%>"/>
<%
}
%>

Related

Dynamically add div in .aspx page

I'm looking for a JavaScript-free way to dynamically add div elements inside a certain element of an aspx web page according to data passed to i.
I'm looking for something similar to razor c# where you can even create loops and write c# code that directly effects the content of the page.
It appears that razor c# doesn't work unless the page is a .cshtml page, so I'm kinda lost here since I don't want to use JavaScript.
Is there a better approach to it?
Say, below is the placeholder div
<div id = "maindiv">
<asp:PlaceHolder ID ="maindivs" runat="server">
</asp:PlaceHolder>
</div>
Then you may add divs to your placeholder div like below
protected void addmainDiv(int m)
{
for(int i = 0; i< m; i++)
{
System.Web.UI.HtmlControls.HtmlGenericControl newdivs = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
newdivs.Attributes.Add("class", "maindivs");
newdivs.ID = "createDiv";
newdivs.InnerHtml = " I'm a div, from code behind ";
maindivs.Controls.Add(newdivs);
}
}
If you want to create HTML dynamically in .aspx then you can create your html code in your .cs (backend file)
string htmlAsStringToShow = "<div>" + variable + "</div>";
Then show its content in your .aspx page like this :
<%= htmlAsStringToShow %>

How to use a Variable or Function to declare my SqlDataSource ID in HTML

I'm writing a for loop that displays a list of links with some chartfx display. The chartfx needs an sqlDataSource. I'm trying to give the unique ID each time the for loop does one iteration but I can not pass it a value or function. Example below in my code.
getSQLID() is just a function that returns a string which I want to be my ID. This is all done on the aspx page and the function is in the .cs . Any help would be really appreciated thank you.
//name of the contentplace holder on the aspx page
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server" >
//code behind
Control ctrl = LoadControl("WebUserControl.ascx");
Control placeHolderControl = this.FindControl("Content2");
Control placeHolderControl2 = this.FindControl("ContentPlaceHolder1");
ctrl.ID = "something";
if (placeHolderControl != null)
placeHolderControl.Controls.Add(ctrl);
if (placeHolderControl2 != null)
placeHolderControl2.Controls.Add(ctrl);
First of all, recall that server controls declared in the designer like this are attached to your class at compile time. So it doesn't make sense to try to create multiple instances in a loop at runtime, and that's why the values in e.g. the Id tag have to be known at compile time.
One alternative is to create them in the code behind, with something like:
for (int i=0; i<2; ++i)
{
var chart = new Chart();
chart.Id = "chartId" + i;
chart.DataSourceId = "srcid" + i;
var src = new SqlDataSource();
src.Id = "srcid" + i;
Controls.Add(chart); // either add to the collection or add as a child of a placeholder
Controls.Add(src);
}
In your case converting all of those declarative properties to the code behind can be a bit of work (though it is possible). An alternative is to make a user control (ascx) that contains the markup that's now in your aspx page. You would instantiate the controls in your code behind with something like:
for (int i=0; i<2; ++i)
{
var ctrl = LoadControl("~/path/to/Control.ascx");
ctrl.Id = "something_" + i;
Controls.Add(ctrl); // again, either here or as a child of another control
// make the src, hook them up
}

How to create an array of User Controls programmatically

How do I programmatically create an array of web user controls?
I created a web user control. I already know how to implement one of them coding in the aspx file, however I would like to know if it is possible to do that from the code behind in either the Page_Init() or the Page_Load() event.
I already know the initialization on the aspx page.
<%# Register TagPrefix="uc" TagName="myUsercontrol1" Src="/Controls/myUsercontrol1.ascx" %>
In the traditional way, I would do something like:
<div id="divMyusercontrols" runat="server">
<uc:myUsercontrol1 id="ctlTheControl" runat="server" />
</div>
What I was wanting to do, which does not work, as I tried, is:
In the aspx file:
<div id="divMyusercontrols" runat="server">
</div>
In the code behind in let us say the Page_Init() event the following:
String strControl = "<uc:myUsercontrol1 id="ctlTheControl{0}" runat="server" />";
String strHtml = null;
for (int i = 0; i < 5; i++)
strHtml += String.Format(strControl, i.ToString());
this.divMyusercontrols.InnerHTML = strHtml;
This code sadly does not work. I realize that I can simply do that manually, but I do not know the actual count. I will know that ahead of time.
UPDATE (to show answer #3 proper code):
The C# for the aspx file is the following. I have a call to a static C# code behind, which returns the count. I then set a property to indicate which item to show and then the for-loop. Cool!
<%int iCount = MyProject.Items;%>
<%for (int iIndex = 0; iIndex < iCount; iIndex++)%>
<%{ %>
<div runat="server">
<uc:myUsercontrol1 id="ctlItem<%=iIndex %>" runat="server" />
</div>
<%}%>
SOLUTION (2013-02-12):
I tried out all three answers below, sadly after I marked one as a solution. The winning one is a modified version of the Page_LoadControl(). Here is the code that works, and yes, I ran the code. Everything works.
// Load an array of controls onto a predefined panel.
for (int iIndex = 0; iIndex < 10; iIndex++)
{
// Load the control.
MyProject.Controls.MyControl ctlItem = (MyProject.Controls.MyControl)Page.LoadControl(#"/Controls/MyControl.ascx");
// Initialize the control.
ctlItem.MyIndex = iIndex;
// Add the control to the panel.
this.pnlItems.Controls.Add(ctlItem);
}
Here is the fixed aspx code.
<div id="divItems" runat="server" class="divItems">
<dx:ASPxPanel ID="pnlItems" runat="server" Width="200px">
</dx:ASPxPanel>
</div>
I tried doing, MyProject.Controls.MyControl ctlItem = new MyProject.Controls.MyControl(), however that does not work. I got a null excemption. Loading the control worked.
The answer, which I too hastilly marked as a solution, does not work. When ran the designer complained. Here is the code from the designer.
/// <summary>
/// ctlPurchases<%=iIndex %> control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::MyProject.Controls.MyControl ctlItem<%=iIndex %>;
The designer was unhappy about the <%...%> part. This solution has other problems. The cleanest one is using the Page_LoadControl.
Can you use an ASP.NET Panel and use Page.LoadControl()?
for (int i = 0; i < 10; i++)
{
pnlContent.Controls.Add(Page.LoadControl("ucDemo.ascx"));
}
This is in C# BTW.
Or if these UserControls will be data bound, you could try using a Repeater control.
When I want multiple copies of my user control I usually follow the pattern below
<%for (Counta = 1; Counta <= 10; Counta++) {%>
<div id="divMyusercontrols<%=Counta%>" runat="server">
<uc:myUsercontrol1 id="ctlTheControl<%=Counta%>" runat="server" />
</div>
<%}%>
The code above would give me 10 UserControls nested inside 10 div elements
UPDATE
Please note that I have used an on-line tool to convert the code from VB to c# So how accurate it is I don't know. Yet I don know it works for me in VB.
The VB Code is below for comparison
<%for Counta = 1 To 10%>
<div id="divMyusercontrols<%=Counta%>" runat="server">
<uc:myUsercontrol1 id="ctlTheControl<%=Counta%>" runat="server" />
</div>
<%Next%>
I think you can do in Page_Load:
HtmlGenericControl control = FindControl("divMyusercontrols")
var myControl = new MyControl();
for(int i=0; i<numberOfUserControls; i++)
{
myControl.ID = "myUniqueID" + i;
}
myControl.Controls.Add(myControl);

Find div at run time at server side in c#

Hye all.
i have div in index.aspx page like this
<div id="MainDiv" runat="server">
and i am creating div from server side(At run time) like
for (Int32 i = 0; i < 4; i++)
{
//Create here divFinal
HtmlGenericControl divFinal = new HtmlGenericControl("div");
divFinal.ID = i.ToString();
divFinal.Attributes.Add("class", "column");
mainDiv.Controls.Add(divFinal);
//add to maindiv
HtmlGenericControl div = new HtmlGenericControl("div");
div.ID = "t_e_" + i.ToString() + "_a";
div.Style["background-color"] = "#CFD8E6";
div.Attributes.Add("class", "grid");
div.Attributes.Add("onclick", "OnMouseDownDiv(this)");
div.Attributes.Add("onmouseover", "OnMouseDown(this)");
div.Attributes.Add("onmouseout", "OnMouseUp(this)");
divFinal.Controls.Add(div);
// add to dvfinal
}
After gen rate its look like this in HTML form
<div id="mainDiv"><div id="0" class="column"><div id="t_e_0_a"></div></div><div id="1" class="column"><div id="t_e_1_a"></div></div></div>
Now I need to find div id t_e_0_a inside main Divdiv.
HtmlGenericControl div =
((HtmlGenericControl)showdiv.FindControl("0"));
But its give me error....
You can't do it like you want as it is not a control. You should place runat="server" attribute on it, or you can get it somehow from showdiv.InnerHtml - there it should be presented as a string which you can parse with some HTML parser for .net (for instance, HTMLAgilityPack suggested here)
To create server side controls at run time, you can use something like below:
for (Int32 i = 0; i < 2; i++)
{
HtmlGenericControl div = new HtmlGenericControl("div");
div.ID = i.ToString();
div.InnerHtml = i.ToString();
div.ClientIDMode = ClientIDMode.Static; //this is for .NET 4.5 only. Required to have ClientID the same as ID.
showdiv.Controls.Add(div);
}
and than, after controls are added, you should be able to use something like this:
HtmlGenericControl div=((HtmlGenericControl)showdiv.FindControl("1"))
to get those controls. But please remember that controls added like that, must be added for each request.
you should have tried with recursive function that how Page.FindControl works.
private Control getFollowingControl(Control c, string key,out Control returnControl)
{
if(c.hasChild)
{
foreach(Control item in c.controls)
{
getFollowingControl(item,key,out returnControl);
}
}
else
{
if(c.Id==key)
{
returnControl=c;
break;
}
}
}
Now you can use above recusive function to find any control at any depth....
Control getThisControl=null;
getFllowingControl(this,"myButton1",out getThisControl);
At the end it would give you the control that has Id="myButton1" in GetThisControl control object.

Variable does not exist in the current context

I'm new to C# .NET. I would like to ask how this works... What I want is just to show an age selection from 1 to 100.
Inside the .aspx file I put this code, I used data binding for the variable listAge.
<asp:DropDownList ID="AgeDropDown" runat="server">
<%# listAge %>
</asp:DropDownList>
Here's the code-behind for it:
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 1; i < 101; i++)
{
string listAge;
listAge = "<asp:ListItem>"+ i +"</asp:ListItem>";
}
}
The error shown inside the .aspx is:
Error Creating Control: AgeDropDown - Code blocks are not supported in this context.
Because of the variable listAge?
Thank you for the help!
Drop the <% %> section in .aspx and in code behind you should do something like this:
protected void Page_Load(object sender, EventArgs e)
{
AgeDropDown.Items.Clear();
for (int i = 1; i < 101; i++)
{
AgeDropDown.Items.Add(new ListItem(i.ToString(),i.ToString()));
}
}
From another point of view there are several flaws in your code:
You are generating ASP.NET tags in code behind. ASP tags are processed on the server and are rendered into html tags. You were practically inserting a tag in html, which browsers will render as simple text since it's not a valid HTML tag.
You were creating a new listAge variable on each iteration of the for loop. Even if the code would work it would display just the last item
You could use the server version of AgeDropDown.
ListItem li;
for (int i = 1; i < 101; i++)
{
li = new ListItem(i.ToString(), i.ToString());
AgeDropDown.Items.Add(li);
}
Is this in asp.net or MVC?
Probably
... <%# listAge %>
should be
... <%= listAge %>

Categories