I am trying to add a check box, label and DDL to ASP.NET page (aspx) from my back class in C#. I have been using LiteralControl _liText = new LiteralControl(); to attach label so that I can show them using this.Controls.Add(_liText);in CreateChildControls() method.
How do I add DDL and check box to ASp.NET page from C# code so that my label is in the same line with DDL and checkbox?
I have already made DDL using this syntax:
List<DropDownList> _ddlCollection=new List<DropDownList>();
for (int i = 0; i < 5; i++)
{
_ddlCollection.Add(new DropDownList());
}
Problem is not in this.Controls.Add() which I call from CreateChildControls(). It is OnPreRender() method where I fill ddl and check box. Is LiteralControl class good for this? Here is what I have tried in OnPReRender():
foreach (SPList list in web.Lists)
{
if (!list.Hidden)
{
_liText.Text += #<input type="checkbox">;
_liText.Text += list.Title + "<br />";
}
}
Your controls exist but the page or user control are not aware of them.
You need to add your control to the page
Page.Controls.Add(_ddlCollection);
You can also add your controls to other controls on the page, for example a panel.
panel1.Controls.Add(_ddlCollection);
You are adding a list of dropdowns which I don't think is what you want.
You need to add ListItems instead.
var dropDown = new DropDownList {Id = "dropDown1"};
dropDown.Items.Add(new ListItem("text", "value");
Page.Controls.Add(dropDown);
Add a label for the dropdown.
Page.Controls.Add(new Label {AssociatedControlId = dropDown.Id, Text = "Drop me down"});
For your other controls follow the same process:
Add a checkbox
Don't add an html control to a literal unless that is really what you want.
If you want to be able to access that checkbox in the code behind then you need to add it as an asp.net control. User a placeholder.
placeHolder1.Controls.Add(new CheckBox {Id = "chkBox", Text="Tick me"});
The text property on the checkbox will be the label for the check box and tick/untick the check box when you click on the text.
Output should be
<label for="dropDown1" >Drop me down</label>
<select id="dropDown1" >
<option value="value" >text</option>
</select>
<input type="checkbox" id="chkbox" />
<label for="chkbox" >Tick me</label>
First, you should add a placeholder.
<form id="form1" runat="server">
<asp:PlaceHolder runat="server" ID="phMain"></asp:PlaceHolder>
</form>
Next, if you have add in one line you use table (It is a simple but not recommended method, next step add all to Page and set css style for the page).
protected override void CreateChildControls()
{
base.CreateChildControls();
Table table = new Table();
for (int i = 0; i < 3; i++)
{
TableRow tr = new TableRow();
TableCell tc1 = new TableCell();
tc1.Controls.Add(new LiteralControl(String.Format("Line {0}",i)));
tr.Cells.Add(tc1);
TableCell tc2 = new TableCell();
CheckBox chb = new CheckBox();
chb.ID = String.Format("CheckBox_{0}", i);
chb.Text = String.Format("CheckBox {0}", i);
chb.CheckedChanged += chb_CheckedChanged;
chb.AutoPostBack = true;
tc2.Controls.Add(chb);
tr.Cells.Add(tc2);
TableCell tc3 = new TableCell();
DropDownList ddl = new DropDownList();
ddl.ID = String.Format("DropDownList_{0}", i);
ddl.Items.Add("1111");
ddl.Items.Add("2222");
ddl.Items.Add("3333");
ddl.SelectedIndex = i;
ddl.Enabled = false;
tc3.Controls.Add(ddl);
tr.Cells.Add(tc3);
table.Rows.Add(tr);
}
phMain.Controls.Add(table);
}
void chb_CheckedChanged(object sender, EventArgs e)
{
CheckBox chb = sender as CheckBox;
string ddlid = chb.ID.Replace("CheckBox", "DropDownList");
DropDownList ddl = this.Page.FindControl(ddlid) as DropDownList;
if (ddl != null)
{
ddl.Enabled = chb.Checked;
}
}
Related
I am creating a page in asp.net where an update panel is added dynamically, and few controls(button,table) are created and added to update panel dynamically.
Below is the piece of code:
UpdatePanel up = new UpdatePanel();
up.ID = newRequests.Tables[0].Rows[i].ItemArray[1].ToString() + "up" + i.ToString();
up.UpdateMode = UpdatePanelUpdateMode.Always;
// create table
HtmlGenericControl table=new HtmlGenericControl("table");
HtmlTableRow toprow = new HtmlTableRow();
HtmlTableCell topleftcell = new HtmlTableCell();
HtmlTableCell toprightcell = new HtmlTableCell();
// create button
Button add = new Button();
add.Text = "Approve";
add.ID = newRequests.Tables[0].Rows[i].ItemArray[1].ToString() + "btn" + i.ToString();
toprightcell.Controls.Add(add);
toprightcell.Controls.Add(new LiteralControl(" "));
// add trigger to update panel
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = add.ID;
trigger.EventName = "Click";
up.Triggers.Add(trigger);
toprow.Controls.Add(topleftcell);
toprow.Controls.Add(toprightcell);
table.Controls.Add(toprow);
up.ContentTemplateContainer.Controls.Add(table);
div.Controls.Add(up);
divNR.Add(div);
Below is div tag where update panel is added dynamically.
<div id="div_AMContainer" runat="server" class="panelContainer">
</div>
Problem is:
When I click on button first time, there is no postback.
But on second click, page is reloaded.
Am I missing something here.?
I want the checkbox control to be added dynamically with different id's in different th tags generating in a loop
<table border="1">
<thead>
<%string j = " Check"; %>
<%for (int i = 0; i < 10;i++ )
{%>
<th style="padding:2px; width:500px;">Table Head<br /><br />
<%
CheckBox chk = new CheckBox();
chk.ID = i + j;
chk.Text = "I am " + i + j;
%>
//I want this checkbox to be added dynamically here with different id's in different th tags generating in a loop
<asp:CheckBox runat="server" ID="<%=i+j%>"/>
</th>
<%} %>
</thead>
</table>
the way to do this is to create yourself a server-control with all the parameters you need, creating the controls in the OnInit, and rendering html in the RenderControl, and accessing the controls from public props like this:
public class DynamicCbs : Control
{
public int CtrlsCount { get; set; }
public List<CheckBox> lstCheckBoxs;
/// decleration of controls must be in the OnInit since the next stage of the page life cycle is to connect whatever came back from the client to the server
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
lstCheckBoxs = new List<CheckBox>();
for (int i = 0; i < CtrlsCount; i++)
{
string id = "DynamicCbs" + i;
CheckBox cbx = new CheckBox()
{
ID = id,
Text = "i am " + id
};
lstCheckBoxs.Add(cbx);
//add controls to control tree
this.Controls.Add(cbx);
}
}
/// here you must build ur html
public override void RenderControl(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Thead);
foreach (var cbx in lstCheckBoxs)
{
writer.RenderBeginTag(HtmlTextWriterTag.Th);
cbx.RenderControl(writer);
writer.RenderEndTag();
}
writer.RenderEndTag();//thead
writer.RenderEndTag();//table
}
}
full example
ok I found the solution. I have use asp:Table control to solve this problem
My aspx page code is :
<asp:Table ID="ObjectwiseTable2" runat="server"
CssClass="AccessTable" BorderColor="Black" width="100%">
</asp:Table>
My .cs page code to Add content and dynamic content in the table is :
TableHeaderRow thead = new TableHeaderRow();
TableHeaderCell th = new TableHeaderCell();
th.Controls.Add(new LiteralControl("Object Wise Detail(s)"));
th.RowSpan = 2;
thead.Cells.Add(th);
int totalUsers = accesswiseDt.Rows.Count;
for (int User = 0; User < totalUsers; User++)
{
TableHeaderCell th2 = new TableHeaderCell();
th2.Controls.Add(new LiteralControl(accesswiseDt.Rows[User]["users"].ToString()));
IsReviewPending = view_access.IsWaitingForViewAccess(ApplicationTree.SelectedNode.Value, Session["empCode"].ToString(), accesswiseDt.Rows[User]["empcode"].ToString());
if (IsReviewPending)
{
th2.Controls.Add(new LiteralControl("<br />"));
CanReviewAccess = true;
//Code for Adding Dynamic control in specific cell of the table
CheckBox chk = new CheckBox();
chk.ID = ApplicationTree.SelectedNode.Value + "_" + accesswiseDt.Rows[User]["empcode"].ToString();
chk.Text = "Access Reviewed";
th2.Controls.Add(chk);
}
thead.Cells.Add(th2);
}
Is there a way to add Ajax CalendarExtender to a dynamic ASP.NET textbox control? Basically I'm trying to do the following:
protected void Page_Load(object sender, EventArgs e)
{
database.DB myDB = new database.DB();
DataTable myVars = new DataTable();
string myTopicID = (string)Session["myTopicID"];
bool myInvite = (bool)Session["myInvite"];
bool mySig = (bool)Session["mySig"];
string myLogo = (string)Session["myLogo"];
string myImage = (string)Session["myImage"];
string myLanguage = (string)Session["myLanguage"];
myVars = myDB.getVarFields(myTopicID, myLanguage);
AjaxControlToolkit.CalendarExtender calenderDate = new AjaxControlToolkit.CalendarExtender();
for (int i = 0; i < myVars.Rows.Count; i++)
{
Label label = new Label();
TextBox text = new TextBox();
label.Text = Convert.ToString(myVars.Rows[i]["varName"]);
myPlaceHolder.Controls.Add(label);
text.ID = Convert.ToString(myVars.Rows[i]["varName"]);
myPlaceHolder.Controls.Add(new LiteralControl(" "));
myPlaceHolder.Controls.Add(text);
if (Convert.ToString(myVars.Rows[i]["varName"]).Contains("Date:"))
{
calenderDate.TargetControlID = "ContentPlaceHolder1_" + text.ID;
myPlaceHolder.Controls.Add(calenderDate);
}
myPlaceHolder.Controls.Add(new LiteralControl("<br />"));
}
}
The error I get when I run the code above is the following:
The TargetControlID of '' is not valid. A control with ID 'ContentPlaceHolder1_Date:' could not be found.
Which makes sense I suppose since the actual text box does not exist yet. But is there a way around this?
I think ASP.NET will be smart enough to handle it if you just use text.ID, you shouldn't need to add the ContentPlaceHolder1_ prefix.
If that doesn't work, you can use the TextBox' ClientIdMode property to set it to static, then text.ID will definitely work.
The following code worked locally for me:
AjaxControlToolkit.CalendarExtender calenderDate = new AjaxControlToolkit.CalendarExtender();
for (int i = 0; i < 2; i++)
{
Label label = new Label();
TextBox text = new TextBox();
label.Text = Convert.ToString("varName");
ph1.Controls.Add(label);
text.ID = "myId" + i;
ph1.Controls.Add(new LiteralControl(" "));
ph1.Controls.Add(text);
calenderDate.TargetControlID = text.ID;
ph1.Controls.Add(calenderDate);
ph1.Controls.Add(new LiteralControl("<br />"));
}
Only differences I think you may want to investigate: I'm using latest ControlToolkit from Nuget, I'm using a ToolkitScriptManager instead of default ScriptManager. One thing that may be important to you is making sure you make text.ID unique.
I have a method which is intended to dynamically generate a series of divs based on the entry of a value from a dropdown list. However, I wish to reuse the same code to generate the tables on the first page_load when a number already exists.
This is where the method is called. It is called GenerateTables and it is called from the Page_Load event:
if (!IsPostBack)
{
AcademicProgramme programme;
if (Request.QueryString["id"] != null)
{
programme = academic.GetAcademicProgramme(Request.QueryString["id"]);
programmeName.Text = programme.Name;
PopulateView(programme);
GenerateTables(programme.Levels);
}
}
And here is the method itself (apologies for the size of the method):
private void GenerateTables(int count)
{
for (int i = 1; i < count + 1; i++)
{
LiteralControl title = new LiteralControl();
LiteralControl close = new LiteralControl();
LiteralControl close2 = new LiteralControl();
String script = "<div class=\"ModuleProgTable\"><h3>Level " + i + "</Modules></h3></br>";
title.Text = script;
AcademicTable.Controls.Add(title);
Panel panel = new Panel();
panel.ID = "Level" + i + "Modules";
PopulatePanel(panel, GetModulesSession(i));
Button a = new Button();
a.ID = "AddModule" + i;
a.Text = "Add Module";
a.Click += (OpenPopup);
AcademicTable.Controls.Add(panel);
AcademicTable.Controls.Add(a);
close.Text = "</div> <!-- Close here -->";
close2.Text = "</div>";
AcademicTable.Controls.Add(close);
}
}
The divs are clearly being populated because if I change the dropdown option then they appear on the PostBack without fail. It's when I try to get them to render on the first page_load that I am having problems.
Any feedback and advice would be greatly appreciated!
Regards,
-Michael
I have some settings stored in web.config like this:
<add key="Answers" value="radiobutton1,radiobutton2,radiobutton3"/>
Radiobutton1, radiobutton2 and radiobutton3 are radiobutton label values.
In settings.cs I have a function to retrieve value from web.config:
public static string Answers
{
get
{
return System.Configuration.ConfigurationManager.AppSettings["Answers"];
}
}
.ascx file:
<table runat="server" OnPreRender="Radio_PreRender" id="table1" name="table1">
</table>
My ascx.cs file contains this function:
protected void Radio_PreRender(object sender, EventArgs e)
{
if (Settings.Answers != "")
{
int counter = 0;
string a = Settings.Answers;
string[] words = a.Split(',');
StringWriter stringwriter = new StringWriter();
HtmlTextWriter writer = new HtmlTextWriter(stringwriter);
foreach (string word in words)
{
writer.WriteBeginTag("tr");
writer.WriteBeginTag("td");
writer.Write("abc123");
RadioButton rdb1 = new RadioButton();
rdb1.Checked = true;
rdb1.GroupName = "rdbgroup";
rdb1.ID = "radiobutton" + counter;
rdb1.Text = word;
table1.Controls.Add(rdb1 );
writer.WriteEndTag("td");
writer.WriteBeginTag("tr");
table1.Render(writer);
counter++;
}
}
}
In other words, I want to generate a dynamic number of this code inside table1:
<tr>
<td>
// input type="radiobutton" and label go here.
</td>
</tr>
At the moment radiobuttons are not generated, because they can't be direct child elements to a table. If I specify a div instead, radiobuttons are generated, but everything I try to write with HtmlTextWriter is not. I understand that my html has to be rendered by using table1.Render(writer); or something similar, but I can't figure it out.
You can try creating a table and add it to the page you are working on, using the exmaple below you can replace the textbox with a radiobutton
Here is an example:
//Creat the Table and Add it to the Page
Table table = new Table();
table.ID = "Table1";
Page.Form.Controls.Add(table);
// Now iterate through the table and add your controls
for (int i = 0; i < rowsCount; i++)
{
TableRow row = new TableRow();
for (int j = 0; j < colsCount; j++)
{
TableCell cell = new TableCell();
TextBox tb = new TextBox();
// Set a unique ID for each TextBox added
tb.ID = "TextBoxRow_" + i + "Col_" + j;
// Add the control to the TableCell
cell.Controls.Add(tb);
// Add the TableCell to the TableRow
row.Cells.Add(cell);
}
// Add the TableRow to the Table
table.Rows.Add(row);
}
I do this quite often by running the user control through its full asp.net lifetime and getting it as a string:
http://www.diaryofaninja.com/blog/2009/09/14/a-simple-solution-to-viewing-a-preview-of-any-page-in-your-site
This way you can use ASP.Net as a templating engine for anything
Page tempPage = new Page();
UserControl myUserControl = new MyUserControl();
tempPage.Controls.Add(myUserControl);
StringWriter sw = new StringWriter();
HttpContext.Current.Server.Execute(tempPage, sw, false);
if (!String.IsNullOrEmpty(sw.ToString()))
{
return sw.ToString();
}