ASP Lifecycle with dynamic DropDownList and Postbacks - c#

Good afternoon.
I am attempting to create a DropDownList populated in 2 ways:
The options are from an Enumeration, listing each possible option.
The selected value is from a database table.
The DropDownList's SelectedIndexChanged takes care of updating the database for me.
Note that the control is working already, but I think I'm not understanding the lifecycle correctly and would like some clarification.
On PageInit, I generate a Table with Headers and one of the cells having my DropDownList.
//Essentially an ArrayList with "row" information (it uses a Field class with
//several parameters, each corresponding to 1 column in the table
GenericFieldsCollection data = new GenericFieldsCollection();
data.FillFieldList();
Table TableToEdit = new Table();
TableHeaderCell Header_FieldName = new TableHeaderCell();
(...)
foreach (GenericField row in data.FieldList)
{
(...)
//The cell with the DDL:
TableCell Column_GraphName = new TableCell();
Column_GraphName.Controls.Add(GenerateGraphSelectionDropdown());
(...)
}
Obviously, if I do not generate it here, the Click events won't work.
This procedure only queries the database with a Select, no updates are made.
After the first (!PostBack) call, subsequent calls can be triggered by changing the DropDownList's index (it has AutoPostBack=true).
So, my PageInit runs again, as expected. And, after Load Number 15 in here happens (
OnXXX (control event)), and my database gets updated.
Later in the Cycle (OnPreRender), I tried clearing the Div anchor I'm using for this table of all controls, and call my GenerateFieldCollectionTable() again. Since my update query in my DropDownList's SelectedIndexChanged event has already executed, I expected to see the updated values. However, doing this will show the old value, and wreck the behaviour (I won't be able to change anything and there is no change in the database).
After a bit of testing, I found out that Page_PreRender having this line is the issue:
------> //TableToEditGraphFields.Controls.Clear();
GenerateFieldCollectionTable();
Clearing the controls of TableToEditGraphFields, an action that happens AFTER CLICK EVENTS (since
Control.OnPreRender is #22 and OnSelectedIndexChanged is #15), means that on the next PostBack the Controls won't trigger click events, as they've been cleared. Is there a part of the cycle where I can process the Click event, rebuild the controls, and still have them clickable on the next PostBack?
Thank you in advance.
EDIT: Code that generates the table:
GenericFieldsCollection data = new GenericFieldsCollection();
data.FillFieldList();
Table TableToEdit = new Table();
TableToEdit.CssClass = "table";
TableRow Headers = new TableRow();
TableHeaderCell Header_FieldName = new TableHeaderCell();
Header_FieldName.Text = "Field Name";
Headers.Cells.Add(Header_FieldName);
//Repeat for each header
TableToEdit.Rows.Add(Headers);
foreach (GenericField row in data.FieldList)
{
TableRow currentRow = new TableRow();
//Repeat for each column; example with the "Order" column
TableCell Column_Order = new TableCell();
TextBox editableOrder = new TextBox();
editableOrder.Attributes.Add("FieldName", row.Name);
editableOrder.Attributes.Add("FieldTable", row.Table);
editableOrder.AutoPostBack = true;
editableOrder.TextChanged += EditableOrder_TextChanged;
editableOrder.Text = row.Order.ToString();
Column_Order.Controls.Add(editableOrder);
currentRow.Cells.Add(Column_Order);
TableToEdit.Rows.Add(currentRow);
}
TableToEditGraphFields.Controls.Add(TableToEdit);

" I'm not understanding the lifecycle correctly and would like some clarification."
How does the life cycle work?
As you can see in the picture below. This is how the life cycle is working.
All the information is from codedisplay There is a lot more information for you to read.

Related

eventhandling for dynamically created checkboxes in a table in asp.net

I am new to asp.net and c# and have to deal with the event handling for a dynamically created table.
The Background:
I have a method in my code-behind CSS file and there, I create dynamically a table to show users in the first column and for every user, I have a checkbox in the second column. My table is displayed well, so the creation is not the problem.
My problem is, that I need event-handling. The goal is, to "mark" users by clicking their appropriate checkbox and then to do, whatever I should do with such users.
I have added the code for event handling with "+=" and I have also tried to use an event handler object. But the problem is: my event-handling code is never reached (i checked this by running and debugging the code).
I'm totally new to asp.net and c# and HTML, javascript and so on. So i don't know much about page-life-cycle and things like that. And it will last time, to get in, cause im a student and I'm just working 2 days a week. If anybody can explain me, how I can do event handling in c# and asp.net for dynamically created elements, that would help me much. Thanks for every help :)
foreach (ListItem li in list_deletedUsers.Items)
{
String s = li.Text;
//Creating the basic Elements
TableRow myrow = new TableRow();
TableCell cellone = new TableCell();
TableCell celltwo = new TableCell();
CheckBox cb = new CheckBox();
//cb.CheckedChanged += cb_CheckedChanged;
//cb.CheckedChanged += this.cb_CheckedChanged;
//cb.CheckedChanged += new
System.EventHandler(cb_CheckedChanged);
//Setting the values and adding cells to row
cellone.Text = s;
myrow.Cells.Add(cellone);
celltwo.Controls.Add(cb);
celltwo.ApplyStyle(tableStyle);
myrow.Cells.Add(celltwo);
//Third Column Cell for further use
//TableCell cellthree = new TableCell();
//cellthree.BackColor = System.Drawing.Color.AliceBlue;
//Adding to Row
//myrow.Cells.Add(cellthree);
//Adding to TableBert
TableBert.Rows.Add(myrow);
}
Here in this methode i create the table:
public void rbe_changed(object sender, EventArgs e)
{
//do some stuff
//look for the user list
//create the table like i show above
}

RadGrid GridTemplateColumn dynamically added insert mode

I've RadGrid where I want to add a column dynamically so I've done something like this in page load
GridTemplateColumn gtc = new GridTemplateColumn();
gtc.DataField = "chqNumber";
gtc.HeaderText = "Cheque Number";
gtc.UniqueName = "chqNumber";
RadGrid1.MasterTableView.Columns.Add(gtc);
It work fine, now I want to add textbox in this column as the user click "+add new record" on grid here is my code of itemCreated event
GridEditableItem gdit = (GridEditableItem)e.Item;
RadTextBox txtBox = new RadTextBox();
txtBox.ID = "someIDWhatEver";
gdit["chqNumber"].Controls.Add(txtBox);
but this textbox gets added to another new column what I mean is this textbox does not added to same chqNumber column you can view my attached image which will illustrate better
as you can see my dynamic column gets added at the last even after insert and cancel button and dynamic textbox doesn't gets in this column please avoid my english grammatical mistakes :P

How can I get the value of a dynamically created checkbox when the submit button is clicked?

I have a asp.net page that has two controls on it, A placeholder and a submit button. During the Page_Load I create a checklist of tasks dynamically. Each row consists of a description, link to a tutorial, and a checkbox. All of the information in the row is kept in a database. If the database says the task has been checked, the code sets the checked property to true. The problem I'm having is that when the submit button is clicked I cannot find what the value is of the checked property for all of the checkboxes on the page(about 23 total).
Here is the code to create the checkboxes...
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
if (item.Attributes.Contains("ree_completed"))
checkbox.Checked = (bool)item.Attributes["ree_completed"];
checkbox.EnableViewState = true;
checkbox.ClientIDMode = System.Web.UI.ClientIDMode.Static;
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
checkbox.ID = checkboxId;
Here is the code to try and find the value of the checkbox...
foreach (Entity item in checklistCollection.Entities)
{
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
itemChecked = (bool)ViewState[checkboxId];
if (itemChecked == "true")
** update database **
//CheckBox checkbox = (CheckBox)phchecklist.FindControl(checkboxId);
}
I think I've read every post on this subject and have tried most of them. I have also read about the ViewState but the suggestions that I have read about have not worked. As you can see I also tried finding the checkbox in the controls collection by the id and that also did not work.
I do not recreate the checkboxes when posting back to the page. Some posts mention that you have to recreate the controls but when I tried to do that I received an error message saying it was a duplicate id. The other reason I would prefer not to have to recreate the page is the performance hit. The database is in a Microsoft Dynamic CRM database that is remote.
How do I retain the value of checked property across a post back?
UPDATE: I changed my logic around and fixed the duplicate id error. The page will now recreate all of the controls during the post back. I still cannot find the value of any of the checkbox controls when the submit button is clicked.
Gary
You need to provide an ID for the checkbox control when you create it. Since you are creating multiple checkboxes; one for each row in the database ... you need to add the unique row identifier to the ID. So you need to build the checkbox ID from the row ID (usually the IDENTITY). Example: ">
Then on postback while you are post-processing each row in the table, you can query the request for that specific key value pair. Something similar to this:
foreach (DataRow dr in dataTable.Rows)
Response["chk_" + dr("ID")];
Use Page Init as opossed to page_Load event. As per https://msdn.microsoft.com/en-us/library/ms178472.aspx "Use this event to read or initialize control properties"
In case for that to work you need to add an event handler to dynamically added controls
in your case
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
checkbox.CheckedChanged += checkBox_CheckedChanged;
and then what you need to do in the method
private void CheckBox_CheckedChanged(object sender, System.EventArgs e)
{
...
}
As I commented, you certainly need to create your controls during the Init event, Load is too late. Check out the asp.Net page life's cycle for details.
On a side note, you might want to let ASP.NET handle the controls's ID. You say you need to keep some value in order to get back to the database, you can wrap your checkboxes in a table. You will then be able to iterate through your controls without having to guess their names.
For instance, if your row has a HiddenField followed by your actual CheckBox:
//Please call me during Init
protected void createTheControls() {
TableRow tr;
TableCell td;
CheckBox cb;
HiddenField section, sequence;
foreach (Object item in someList)
{
section = new HiddenField();
section.Value = item.Attributes["ree_sectionnumber"].ToString();
sequence = new HiddenField;
sequence.Value = item.Attributes["ree_sequencenumber"].ToString();
cb = new CheckBox();
cb.ID = String.Concat("checkbox", (String)sequence.Value);
if (item.Attributes.Contains("ree_completed"))
cb.Checked = (bool)item.Attributes["ree_completed"];
td = new TableCell();
td.Controls.Add(section);
td.Controls.Add(sequence);
td.Controls.Add(cb);
tr = new TableRow();
tr.Cells.Add(td);
}
}
protected void readTheControls()
{
foreach (TableRow tr in myTable.Rows)
{
HiddenField section = (HiddenField)tr.Cells[0].Controls[0];
HiddenField sequence = (HiddenField)tr.Cells[0].Controls[1];
CheckBox cb = (CheckBox)tr.Cells[0].Controls[2];
}
}
I notice you try to use the ViewState explicitly, which I believe is not going to be of any help here. The solution above may look cumbersome, but it will ensure you dont need to mess with ID's when fetching the controls.
Here's a thorough explanation from MSDN, and here are a few short and sweet SO answers explaining ViewState's purpose.

Disabling button in DataGridViewButtonColumn

I pull results from Oracle database and store it in DataTable before setting it as source in DataGridView. The reason for this is I remove some columns before I show it to user. Using DataGridViewButtonColumn I have added column that has enables user to "Edit" specific row. My problem is I'm trying to disable that button based on value in that current row. Leave the rest of the row buttons enabled.
var table = OracleConnection.Results(myquery);
table.Columns.Remove("Comments");
var editButton = new DataGridViewButtonColumn;
editButton.Value = "Edit";
editButton.Text = "Edit";
editButton.UseColumnTextForButtonValue = true;
_dtgvResults.Source = table;
_dtgvResults.Columns.Add(editButton);
Take a look in OnRowDataBound event in your DataGridView
MS Reference

Addressing dynamically created TextBox Controls in asp.NET C#

I'm trying to make a page that loads an undefined number of rows into a table, each row containing two columns, one column a string, the other a TextBox. When I click a submit button, i want to be able to retrieve the values entered into each TextBox.
The first half i can do, obviously in the real code this would be in a foreach loop and the textbox ID assigned a unique value i could reproduce later to call it with.
TableCell myCell = new TableCell();
myCell.Text = "StudentID";
TableCell nextCell = new TableCell();
TextBox mytext = new TextBox();
mytext.ID = "TxtBox1";
nextCell.Controls.Add(mytext);
TableRow myRow = new TableRow();
myRow.Cells.Add(myCell);
myRow.Cells.Add(nextCell);
TableStuUploads.Rows.Add(myRow);
When i click my submit button, i try to run this code(just temp code ATM, proof of concept stuff):
TextBox tmptext = (TextBox)FindControl("TxtBox1");
Label1.Text = tmptext.Text;
But that sets tmptext as null, and i get a null pointer exception on the next line. So then i tried
TextBox tmptext = (TextBox)TableStuUploads.FindControl("TxtBox1");
Label1.Text = tmptext.Text;
Same error. Then i tried
foreach (Control x in TableStuUploads.Controls)
{
if (x.GetType().ToString().Equals("System.Web.UI.WebControls.TextBox"))
{
Label1.Text = ((TextBox)x).Text;
}
}
But when debugging this, I see TableStuUploads.Controls has a count of zero.
How am I supposed to address these dynamically created controls? I have searched around, and the answer i got lead me to the three solutions i have already tried. Where am i going wrong?
You are probably not recreating your dynamic controls on post back. This is required to both find each control and retrieve each control's value.
In addition, it would probably be best to use a repeater to create these controls, It is easier to maintain and debug.
Edit
You need to recreate your table on each postback(page_load) like #ShaiCohen says in his answer then you need something ilke:
foreach (TableRow item in TableStuUploads.Rows)
{
TextBox tmptext = (TextBox)item.FindControl("TxtBox1");
Label1.Text = tmptext.Text;
}

Categories