The problem is: On postback, the table does not have the rows that were dynamically created, the rowcount is 0.
Click on the button, it should detect the checked checkboxes within the table dynamically generated.
The table is made by code when the "day" is selected using the drop down list and "the starting date" is selected using the calender.
I know there's a lot of code, but it's the least I thought I had to post, so answerers can debug. Please note I have tried hard but cannot get the solution to this.
Here’s the code:
public partial class DaySelection : System.Web.UI.Page
{
Table table1 = new Table();
Button button1 = new Button();
string the_id_checkbox;
string the_id_label;
//The need of the table ENDS
DropDownList selectdays = new DropDownList();
Label theselecteddate = new Label();
Button extract_the_selected = new Button();
Literal selected_values=new Literal();
int number_of_row = -1;
protected void Page_Load(object sender, EventArgs e)
{
CheckBox check_or_not = new CheckBox();
try
{
selected_values.Text = "";
form1.Controls.Remove(selected_values);
form1.Page.Response.Write("inside try");
for (int i = 0; i < table1.Rows.Count; i++)
{
Response.Write("inside for");
the_id_checkbox = "checkmate" + i;
the_id_label = "The_text" + i;
check_or_not = (CheckBox)table1.Rows[i].FindControl(the_id_checkbox);
if (check_or_not.Checked == true)
{
form1.Page.Response.Write("inside if");
selected_values.Text = selected_values.Text + "<br /> " + check_or_not.Checked.ToString();
selected_values.Text = selected_values.Text + " and the day is: " + ((Label)table1.Rows[i].FindControl(the_id_label)).Text;
}
else
{
Response.Write(" selection no detect");
}
}
form1.Controls.AddAt(1, selected_values);
Response.Write(selected_values.Text);
}
catch (NullReferenceException nn)
{
form1.Page.Response.Write("inside catch" + nn.Message.ToString() + nn.StackTrace);
}
extract_the_selected.Text = "Extract it";
form1.Controls.AddAt(2,extract_the_selected);
selectdays.AutoPostBack = true;
ArrayList thedays = new ArrayList();
thedays.Add("Monday" + DateTime.Now);
thedays.Add("Tuesday");
thedays.Add("Wednesday");
thedays.Add("Thursday");
thedays.Add("Friday");
thedays.Add("Saturday");
thedays.Add("Sunday");
selectdays.DataSource = thedays;
selectdays.DataBind();
form1.Controls.AddAt(3,selectdays);
Calendar1.SelectionChanged += new EventHandler(Calendar1_SelectionChanged);
}
void Calendar1_SelectionChanged(object sender, EventArgs e)
{
DateTime startdate;
string month;
month = Calendar1.SelectMonthText;
startdate = Calendar1.SelectedDate;
days_date(startdate);
}
void selectdays_SelectedIndexChanged(object sender, EventArgs e)
{
display_dates_of_day(DateTime.Parse("9-1-2010"), DateTime.Parse("9-30-2010"), selectdays.SelectedItem.Text);
}
public void days_date(DateTime startdate)
{
int noofdays;
DateTime enddate = new DateTime();
noofdays = DateTime.DaysInMonth(startdate.Year, startdate.Month) - 1;
enddate = startdate.AddDays(noofdays);
Response.Write("<br /> end date is " + enddate);
Response.Write("<br /> start date is " + startdate);
display_dates_of_day( startdate, enddate, selectdays.SelectedItem.Text);
}
void display_dates_of_day(DateTime startDate, DateTime endDate, string selectedday)
{
int Count = 0;
for (DateTime dt = startDate; dt <= endDate; dt = dt.AddDays(1.0))
{
if (dt.DayOfWeek.ToString() == selectedday)
{
table1.ID = "table1";
number_of_row = number_of_row + 1;
string date = dt.Date.ToString("dd-MMMM-yyyy");
for (int adding_rows = 0; adding_rows < 1; adding_rows++)
{
TableRow table_row1 = new TableRow();
TableCell table_cell1 = new TableCell();
TableCell table_cell2 = new TableCell();
Label The_label = new Label();
CheckBox checkmate = new CheckBox();
The_label.Text = date + " (<---date)" + number_of_row;
the_id_checkbox = "checkmate" + number_of_row;
checkmate.ID = the_id_checkbox;
the_id_label = "The_text" + number_of_row;
The_label.ID = the_id_label;
table_cell2.Controls.Add(checkmate);
table_cell1.Controls.Add(The_label);
table_row1.Controls.AddAt(0, table_cell1);
table_row1.Controls.AddAt(1, table_cell2);
table1.Rows.Add(table_row1);
}
button1.Text = "click me to export the value";
form1.Controls.Add(table1);
form1.Controls.AddAt(1, selected_values);
Count++;
}
}
Response.Write("<br /> The count of days by traversing: " + Count);
}
}
The reason you're seeing this seemingly "strange" behaviour is that you're dynamically constructing the contents of Table1 and adding it to the pages .Controls collection only in the display_dates_of_day method, which is called by:
selectdays_SelectedIndexChanged
Calendar1_SelectionChanged (indirectly)
This means that when your page is re-contructed on post-back, the controls don't exist. If you "View Source" in your browser, you'll find that after clicking the button to trigger a post-back you can't find the string "Table1" in the markup, but if you do it after clicking on a date in the calendar, you can. That's because in the "clicking the button" scenario, the control is never populated and added to the page
I'd make a few suggestions to get your head round this and solve the problem:
Start with a much simplified version of this to help you understand the asp.net page lifecycle and how it impacts on what you're doing.
Try to ensure your code adds as few controls as possible to the page dynamically as this makes things a lot simpler. i.e. Make Table1 a control that's declared in the .aspx page.
Related
I've created a dynamic webpage using strictly html, javascript, and MS Access. While it was functional, locally, there were complications deploying it. Since I have ported the data to MySQL and am trying to use Visual Studio's aspx.cs to do much of what the javascript did previously.
I have a screen that populates a dynamic set of rows based on a query result (two rows per record for aesthetics), one of the cells contains a drop down menu(html select/ asp:ListBox).
When I had everything only on javascript, I could create the cell, then create its contents, then set the selected value using:
document.getElementById("StatusDD" + rowCount).value = reader.GetValue(i);
From what I've gathered so far, the rough equivalent is:
ListItem li = StatusDD1.Items.FindByValue(reader.GetValue(i));
li.Selected = true;
However, I cannot simply hardcode StatusDD1 thru StatusDDx (for one, at the beginning my hardcoded set might be larger than the number of records returned, and two eventually the rows returned will be larger than the set of hardcoded values).
So what I did was I created the following function:
protected void setSelected(string selectId, string value)
{
/*Need to put something here to make the following work*/
selectId.Items.FindByValue(value).Selected = true;
}
The selectId being passed in is the name/id of the ListBox and the value is the value coming back from the query.
It's called like:
setSelected("StatusDD" + rowCount, (string)reader.GetValue(i));
If I could, for lack of better phrase, materialize the name created by "StatusDD"+rowCount, I could pass that name in as if I was passing in a ListBox, rather than a string.
Alternatively, if there was a way to select the ListBox from an array where I could do a conditional check WHERE/IF ListBox.Name = selectId, something like the following PseudoCode:
ListBox a = ListBox.NameMatches(selectId);
a.Items.FindByValue(value).Selected = true;
Currently ListBoxes are being created by defining the box in a string and then passing that string into an HtmlTableCell:
HtmlTable myTable = new HtmlTable();
HtmlTableRow newRow;
string cellId;
string cellContents;
int rowCount = 1;
string statusDisabled = "";
while (reader.Read()){
newRow = new HtmlTableRow();
myTable.Rows.Add( newRow );
...
...
cellContents = "<asp:ListBox name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%; " + statusDisabled + "' value='" + reader.GetValue(i) + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><asp:ListItem value='0'></asp:ListItem><asp:ListItem value='1'>New</asp:ListItem>....asp:ListBox>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
}
If it helps, here's how I had it working in javascript:
while (!rs.EOF) {
rowa = table.insertRow(rowCount);
rowa.id = "RECORD" + rowCount + "a";
cell = rowa.insertCell(i + 1);
cell.id = "RECORD" + rowCount + "_CELL" + (i + 1);
for (i = 0; i < 8; i++) {
cell.innerHTML = "<select name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%' value='" + rs.fields(i).value + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><option value='NONE'></option><option value='New'>New</option>...</select>";
if (readonly) {
document.getElementById("StatusDD" + rowCount).disabled = true;
}
document.getElementById("StatusDD" + rowCount).value = rs.fields(i).value;
}
...
}
OK, got the ListBox to work, but as I was researching, and when I finally got it to work, I discovered that what I wanted was the DropDownList, not the ListBox, but the same fixes needed to be done in order to get either to work.
I use the following function now:
protected void setSelected(string selectId, string value)
{
PlaceHolder TCS = Page.FindControl("TestingCS") as PlaceHolder;
DropDownList ddl = TCS.FindControl(selectId) as DropDownList;
if (ddl != null)
{
ddl.SelectedValue = value;
ListItem item = ddl.Items.FindByValue(value);
if(item != null)
{ item.Selected = true;}
}
}
Also, for my cell contents that just contain data using the following is fine:
cellContents = "<someString>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
but for my drop down (or list box) I need to use:
cell = new HtmlTableCell();
newRow.Cells.Add(cell);
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList.ID, (string)(reader.GetValue(i)));
A smoother solution:
protected void setSelected(DropDownList ddl, string value)
{
ListItem item = ddl.Items.FindByValue(value);
if (item != null)
{ item.Selected = true; }
}
...
protected void accessRecord()
{
...
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Attributes["onChange"] = "javascript:markNeedSave(" + rowCount + ");";
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList,(string)reader.GetValue(i));
}
...
It sounds like the function you're looking for is FindControl. This can be used from the Page, or any parent control you might have created to hold your output.
An example implementation of your setSelected method might look like this:
protected void SetSelected(string selectId, string value)
{
var lb = Page.FindControl(selectId) as ListBox;
if (lb != null)
{
var item = lb.Items.FindByValue(value)
if(item != null)
item.Selected = true;
}
}
I've been struggling with this question for a few days now and I haven't found any answer yet; I created a ToolStripMenu array which is filled dynamically from a stored procedure:
ToolStripMenuItem[] itemsDepto = null;
itemsDepto = new ToolStripMenuItem[data.Tables[0].Rows.Count];
for (int i = 0; i <= data.Tables[0].Rows.Count - 1; i++)
{
itemsDepto[i] = new ToolStripMenuItem();
itemsDepto[i].Tag = data.Tables[0].Rows[i].ItemArray[0];
itemsDepto[i].Text = data.Tables[0].Rows[i].ItemArray[1].ToString();
itemsDepto[i].CheckOnClick = true;
itemsDepto[i].Checked = true;
itemsDepto[i].Click += DeptoFilter_Click;
deptoList.Add(data.Tables[0].Rows[i].ItemArray[1].ToString());
}
tsmiDepartamento.DropDownItems.AddRange(itemsDepto);
And what I'm trying to achieve is use this ToolStripMenu as a filter control for the user, by default is Checked so when the user unchecks the menu, it should filter the rows with the content that is unchecked.
In the click event I add and remove values from the list depending on the state of the menu button as you can see in the following example:
private void DeptoFilter_Click(object sender, EventArgs e)
{
ToolStripMenuItem temp = new ToolStripMenuItem();
temp = (ToolStripMenuItem)sender;
BindingSource bind = new BindingSource();
bind.DataSource = dgvPersonalTotal.DataSource;
if (temp.CheckState == CheckState.Checked)
{
deptoList.Add(sender.ToString());
}
else
{
deptoList.Remove(sender.ToString());
}
bind.Filter = "Departamento NOT IN (" + /*LIST*/"" + ")";
dgvPersonalTotal.DataSource = bind;
//foreach (string x in deptoList)
//{
//}
}
But the big question I have is, how can I use a list to filter the Binding Source, as you can see in the code, I can't just use the list or even try use the BindingSource.Filter in the foreach, I don't know how to resolve this problem, so any idea is well appreciated.
bind.Filter = "Departamento NOT IN (" + string.Join(",", deptoList.ToArray()) + ")";
In my ASP.Net page I need to show an HTML div who contains : Images, Text, Arrows and Connectors.
What are my "Connectors" ?
It's an ImageButton, and when the user click on this connector, the HTML div is showing a new content. This connectors are used to navigate in a TreeView.
But my problem is :
I create all my connectors (and all the HTML div content) dynamically. When the user click on the first connector the HTML div is showing new content. But on this second content, when the user click on a connector : nothing. The Click event of the ImageButton is not fired.
This is my Connector creation (on PageLoad and then on each Connector Click) :
List<Connecteur> ListConnecteur = new List<Connecteur>();
ListConnecteur = NomenclatureObj.SelectConnecteurs(DocId, ExterneData.RapidoBDDCnx);
foreach (Connecteur CeConnecteur in ListConnecteur)
{
if (CeConnecteur.FK_docversion_suivant_id != 0)
{
ImageButton ImgBtnTmp = new ImageButton();
ImgBtnTmp.Width = 30;
ImgBtnTmp.Height = 30;
ImgBtnTmp.ImageUrl = "~/images/GreenButton.png";
ImgBtnTmp.Style.Add("left", CeConnecteur.position_x_pix.ToString() + "px");
ImgBtnTmp.Style.Add("top", CeConnecteur.position_y_pix.ToString() + "px");
ImgBtnTmp.Click += new ImageClickEventHandler(ImgBtnTmp_Click);
ImgBtnTmp.CommandArgument = CeConnecteur.FK_docversion_suivant_id.ToString();
ImgBtnTmp.Style.Add("position", "absolute");
DivAffichage.Controls.Add(ImgBtnTmp);
ImgBtnTmp.CausesValidation = true;
}
}
And this is my Connector OnClick :
public void ImgBtnTmp_Click(object sender, EventArgs e)
{
ImageButton ThisBtn = sender as ImageButton;
string CommandArg = ThisBtn.CommandArgument;
int DocId = Convert.ToInt32(CommandArg);
TREEVIEW_NIVEAU++;
//DocId of the clicked connector
Session["DocId"] = DocId;
ClearDiv();
LoadDiv(DocId);
}
EDIT 1 : My whole LoadDiv() function
public void LoadDiv(int DocId)
{
#region Connecteurs
List<Connecteur> ListConnecteur = new List<Connecteur>();
ListConnecteur = NomenclatureObj.SelectConnecteurs(DocId, ExterneData.RapidoBDDCnx);
foreach (Connecteur CeConnecteur in ListConnecteur)
{
if (CeConnecteur.FK_docversion_suivant_id != 0)
{
ImageButton ImgBtnTmp = new ImageButton();
ImgBtnTmp.Width = 30;
ImgBtnTmp.Height = 30;
ImgBtnTmp.ImageUrl = "~/images/GreenButton.png";
ImgBtnTmp.Style.Add("left", CeConnecteur.position_x_pix.ToString() + "px");
ImgBtnTmp.Style.Add("top", CeConnecteur.position_y_pix.ToString() + "px");
ImgBtnTmp.Click += new ImageClickEventHandler(ImgBtnTmp_Click);
ImgBtnTmp.CommandArgument = CeConnecteur.FK_docversion_suivant_id.ToString();
ImgBtnTmp.Style.Add("position", "absolute");
DivAffichage.Controls.Add(ImgBtnTmp);
}
}
#endregion
#region Textes
List<Texte> ListTexte = new List<Texte>();
ListTexte = NomenclatureObj.SelectTextes(DocId, LANGUE_ID, ExterneData.RapidoBDDCnx);
foreach (Texte CeTexte in ListTexte)
{
Label LblText = new Label();
LblText.Text = CeTexte.contenu;
LblText.Width = CeTexte.largeur_voulue_pix;
LblText.Style.Add("left", CeTexte.position_x_pix.ToString() + "px");
LblText.Style.Add("top", CeTexte.position_y_pix.ToString() + "px");
LblText.Style.Add("position", "absolute");
DivAffichage.Controls.Add(LblText);
}
#endregion
#region Images
List<ImageNomenclature> ListImg = new List<ImageNomenclature>();
ListImg = NomenclatureObj.SelectImages(DocId, ExterneData.RapidoBDDCnx);
foreach (ImageNomenclature CetteImage in ListImg)
{
Image ImgTmp = new Image();
ImgTmp.ImageUrl = "~/Nomenclature/RAPIDO/planches/" + CetteImage.fichier_chemin;
ImgTmp.Width = CetteImage.largeur_voulue_pix;
ImgTmp.Height = CetteImage.hauteur_voulue_pix;
ImgTmp.Style.Add("left", CetteImage.position_x_pix.ToString() + "px");
ImgTmp.Style.Add("top", CetteImage.position_y_pix.ToString() + "px");
ImgTmp.Style.Add("position", "absolute");
ImgTmp.Style.Add("z-index", "-1");
DivAffichage.Controls.Add(ImgTmp);
}
#endregion
#region Flèches
List<Fleche> ListFleche = new List<Fleche>();
ListFleche = NomenclatureObj.SelectFleches(DocId, LANGUE_ID, ExterneData.RapidoBDDCnx);
foreach (Fleche CetteFleche in ListFleche)
{
string HTMLCode = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"800\" height=\"600\"><line x1=\"" + CetteFleche.position_x1_pix + "\" y1=\"" + CetteFleche.position_y1_pix + "\" x2=\"" + CetteFleche.position_x2_pix + "\" y2=\"" + CetteFleche.position_y2_pix + "\" stroke=\"#ff0000\"/></svg>";
//DivAffichage.InnerHtml += HTMLCode;
}
#endregion
}
You should create your dynamic control every time on Page_Init or Page_Load if you would like to handle events from them after Postback.
See links below for details:
http://msdn.microsoft.com/en-us/library/y3bwdsh3%28v=vs.140%29.aspx
http://msdn.microsoft.com/en-us/library/hbdfdyh7%28v=vs.100%29.aspx
Here you can see the same problem.
EDIT
Try to do something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
LoadDiv(Session["DocId"])
}
}
I am dealing with a very unusual situation through which made me go through the effort of putting up for some answers.
I am trying to regenerate some controls based on the following document,
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
This approach works TextBox controls but does not seem to respond to Label, Literal, UploadFile or other controls that I'm not aware of.
I do understand this not working for UploadFile due to security reasons, but why not for other non TextBox controls?
The above article suggests that if we maintain the ID of a control, we can retain them after post back but in the following implementation I only get the TextBox responding to this solution. The "Label" and "Literal" controls in this situation are lost after PostBack which is undesirable given that I pretty much follow the recipe line by line.
Can someone please have a look at the following implementation and see where I'm going wrong or if I got the whole concept wrong in a way?
This is a counter to keep track of the number of control sets generated,
protected int NumberOfControls
{
get { return (int)ViewState["NumControls"]; }
set { ViewState["NumControls"] = value; }
}
This is the Page_Load event that fetches the previous slides from the DB on initial page load and regenerates the same page on Postback. AddSlide is a "Placeholder" control where I post other Controls into.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.NumberOfControls = PopulateCarouselSettingFields(AddSlides);
}
else
{
this.GenerateControls();
}
}
This is the definition for "PopulateCarouselSettingsFields".
public static int PopulateCarouselSettingFields(PlaceHolder _AddSlides)
{
string result = string.Empty;
int counter = 0;
string CS = ConfigurationManager.ConnectionStrings["someconn"].ConnectionString;
using (SqlConnection conn = new SqlConnection(CS))
{
SqlCommand SqlCmd = new SqlCommand();
conn.Open();
SqlCmd.Connection = conn;
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCmd.CommandText = "storedprocedure";
SqlDataReader dReader;
dReader = SqlCmd.ExecuteReader();
while (dReader.Read())
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + counter;
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
_AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + counter;
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
_AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + counter;
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
CarouselText.Text = dReader["CarouselText"].ToString();
_AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit5.ID = "Lit2_" + counter;
Lit5.Text = "</div></div></div><br />";
_AddSlides.Controls.Add(Lit2);
counter++;
}
}
return counter;
}
This is supposed to regenerate or re-state all the controls using their IDs upon PostBack called from Page_Load event.
protected void GenerateControls()
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + i.ToString();
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + i.ToString();
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + i.ToString();
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + i.ToString();
AddSlides.Controls.Add(Lit2);
}
}
The following piece of code adds new set of controls to the Placeholder "AddSlides" container.
protected void AddMoreSlidesToCarousel(object sender, EventArgs e)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + NumberOfControls.ToString();
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + NumberOfControls.ToString();
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + NumberOfControls.ToString();
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + NumberOfControls.ToString();
Lit2.Text = "</div></div></div><br />";
AddSlides.Controls.Add(Lit2);
this.NumberOfControls++;
}
I'm sorry to put it like this, but the article you are relying on is doing it wrong.
Dynamically created controls MUST be created in Page_Init, so that they exist before any ViewState stuff. Also, dynamically controls must be recreated each and every time the Page is initialized, PostBack or not.
ViewState/PostBack do not "retain" controls, only the state of such controls.
Please read this article: ASP.NET Page Life Cycle Overview
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