ASP.NET - Dynamic Rows and Page_Load - asp.net

I am having a problem with an C# ASP.NET form. The purpose of the form is to load some key/value pairs from a database to allow a user to view, edit or delete them.
The Key/Value pairs are dynamically generated in the Page_Load event, and everything works well when the page is first openend. Here is some example code (trimmed down from the original)
TableRow row = new TableRow();
TableCell cell = new TableCell();
cell.Text = keyName;
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = keyValue;
row.Cells.Add(cell);
KeyValueTable.Rows.Add(row);
I just loop through all of the Key/Value pairs and each are added dynamically to a table. At the point of page loading, everything is running smoothly, and all Key/Value pairs show as expected.
The problem occurs when a user clicks a button, which since is set to runat="server", generates a post back event. What this does is it appears to do is clear the dynamic content generated above, and then recreates it (since it is created in the Page_Load event).
What I would prefer to do is choose when that dynamic content is cleared, since I don't want it refreshing unnecessarily, since each refresh is actually occurring from a database.
What I have attempted to do is perform the generation of the dynamic content if it isn't a postback. I.E:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GenerateDynamicContent();
}
}
However what that now does is generate the dynamic content when the page first loads, however as soon as some postback event occurs (such as a user clicking a button), the dynamic content is wiped, but not created.
Basically what I am hoping for is to discover some way where I can create dynamic content, as shown above, that isn't wiped on any postback event. I want to be able to control when it is refreshed, rather than it occurring on any postback event. Is this possible?
Many thanks

I've found that putting the dynamic code into Page_Init instead of Page_Load prevents the content from being wiped during a postback

Related

GridView contents don’t update when underlying data changes

So I have an ASP.NET page with two controls:
a GridView which displays rows from a SqlDataSource, and in which the user can select a row;
a DetailsView in which the user can see and edit the values of the selected row.
The DetailsView can update the underlying data, but even though the page reloads, the GridView still displays the old data until I manually reload the page in the browser.
How do I ensure that the GridView displays the correct data after the update in the DetailsView?
P.S. It may be important to note that due to reasons outlined in this other question, I had to use a custom OnItemUpdating event with the DetailsView. This event performs the SQL update command (successfully), sets the DetailsView back to ReadOnly mode (out of Edit mode) and then cancels the event (e.Cancel = true). If this event canceling also somehow cancels the GridView updating, how do I manually tell it to update itself?
P.P.S.: I discovered this similar question, but the answer doesn’t work: it resets the entire page back to pristine state, which means the GridView loses its selected row and the DetailsView disappears. I don’t want that.
on page load:
YourGridViewID.DataBind()
If your OnItemUpdating event generates postback
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
GridView.DataBind();//rebinding it with considering changes DetailView
}
}
If it doesn't work let me know.

Asp Update Panel - Details View Updates Underlying GridView doesn't

I have an Asp.net gridview on a page, when a buttonfield is clicked (instead of select) it opens a popup form (my popup not asp's) which contains the detail of the gridview row displayed in an editable DetailsView. (This approach has been used because the grid contains 20 wideish columns and it is easier to edit / update in the detailsView format) The DetailsView takes any amendmends and writes them back to the table, fine, but the underlying Gridview is never visually updated unless of course the page is completely reloaded (I tried to use the Windows.reload function but I get the annoying winddows is trying to reopen etc, error, so that is useless). I am trying to discover the best way to get the gridview to refresh it's data. I have placed via a Me.ClientScript.RegisterStartupScript(Me.GetType() eyc, an alert box to communicate when the 'update steps' of the detailsview fires so I could interject a gridview.ReBind() but because the detailsview is held within the update panel the, for example, Protected Sub DetailsView2_ItemUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles DetailsView2.ItemUpdated functions, and the roqwupdatind and so one, do not appear to fire. (they must do of course else the table would not be updating. MY problem is how do I 'communicate with update events within the panel contained detailsviews so that I can cause a reBind to occur on the main gridview. Any Ideas would be appreciated. Thank you
Detail view have an event called
protected void dvEbook_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
{
Response.Redirect(Request.RawUrl,false);
}
where dvEbook is my detail view.
It will call a same page.
I hope it will work for you.
Thanks

ASP.NET User Controls - Problem adding multiple instances programmatically?

I have created a user control which basically consists of 3 text boxes. I want to allow the user to click a hyperlink which will add a new instance of the user control onto a PlaceHolder. This seems to be working as I populate one of the text box controls with a random number which changes whenever I click the hyperlink. However, it is overwriting the previous control.
Heres the code on MyPage.aspx
protected void MyHyperlink_Click(object sender, EventArgs e)
{
var uc = new MyUserControl();
uc = (MyUserControl)LoadControl("~/path/to/my/usercontrol.ascx");
placeHolderCtrl.Controls.Add(uc);
}
Basically what I need to know is how can I get the control adding different instances underneath eachother as it just seems to be 1 control being overwritten each time.
Thanks.
The problem is after the postback, your previously added controls are not added to the placeholder. Dynamically added control should be added on each postback. My recommendation is to store a counter in a variable and at your page load, add your web controls again depending to this counter.

How do I add a textbox dynamically in ASP.NET?

I've a following requirement for my asp.net page:
User can add a textbox dynamically on a page A by clicking on link "Add a new category" hyperlink
He clicks submit button on page A and gets redirected to page B.
When he clicks on page A link from this page, the textboxes that he added should be persisted.
Can someone help me with the code on this?
Appreciate your help!
In the ButtonClick Method write.
TextBox tb = new TextBox();
Parent.Controls.Add( tb );
The Parent is the control you want to add the textbox to, for instance a panel.
You can also look at this resource.
Hope it helps.
Adding a user control dynamically is simple. But in this case, I don't think you need to do that, instead you should look at creating a repeater with a textbox inside it, and when the user clicks Add Category, add one item to the repeater datasource.
This way you can handle both control creation and state persistence at the same time.
dealing with dynamic user controls can be a pain in the ass.
as a rule of thumb i follow, whenever you create a dynamic user control, then you must set it's ID so ASP.net can reallocate it on post back, and to keep the controls values after post back you should reload your user controls on Page_Init event.
hope this helps.
Dynamically creating Textboxes:
suppose you have page like this
when you enter '1' in textbox and click on ADD button,output will be like display one textbox
below..
i have designed like this,
i have one textbox and placeholder for displaying dynamic textboxes..
double click on Add button...in btnadd_click,you have to write the following code
protected void btnadd_Click(object sender, EventArgs e)
{
int i;
for (i = 0; i < Convert.ToInt32(txtno.Text); i++)
{
TextBox txtbox = new TextBox();
phtxt.Controls.Add(txtbox);
phtxt.Controls.Add(new LiteralControl("<br>"));
}
}
debug it... and the output is,
As others have stated adding the text box dynamically is fairly straight forward, just create the Textbox and add it to the controls collections wherever you need it to show up. You then need to store the information that this user gets this additional text box. Assuming that this is meant for long term, you will need to store this information in your backend store. Whenever you are constructing the page you will need to read the store information first to see what textboxes to create.
I would suggest doing it as follows. In the Onload event, if you have not done so before, load the dynamic information from your DB. Add any necessary controls to the page and store this information in viewstate. On any subsequent postbacks, read the information from viewstate to add the additional controls. This will save you from having to read constantly from the database on each postback.

Creating custom server control to accept user input

I am trying to build a server control that, depending on a "QuestionTypeId" display either a text box, date picker or Yes-No radio buttons.
I have my control displaying how I want it to, but when the submit button is pressed on the form, the text box, date picker or radio buttons that were generated in the RenderContents method are all null.
I have attempted to store the generated controls in view state, that stopped them being null, but the user inputs were not being stored.
I will post code if it is needed. Just ask.
I think you need to create (and add) the controls in CreateChildControls. This will mean you'll need to store the value of the QuestionTypeId in either Viewstate or ControlState (I'd argue that ControlState is applicable in this case, as your control can't work without this value).
When you add controls dynamically, you need to make sure they are recreated before the viewstate is restored.
I haven't done this in a while, but from memory I think you should recreate your controls in the OnInit method. This happens before postback data has been loaded and before the controls have their values set from viewstate.
It may be worth doing some reading on the asp.net page lifecycle:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
You can create a user control and use server controls for textbox, datepicker, radiobuttons.
If you create a cusom server control then you have to add the posted data to your control properties. You can do this at your control OnInit event:
MyProperty = Request.Form("myControl");
A simpler method would be to create all the controls at design time and make the controls invisible based on you requirements.
Example code:
protected void Page_Load(object sender, EventArgs e)
{
txtBox.Visible = QuestionTypeID == 1;
chkBox.Visible = QuestionTypeID == 2;
}
If you do use dynamic controls you should do as David pointed out, save the value QuestionTypeID in ViewState or ControlState and then create the control you want based on that value.
(the control needs to be created every time the page loads even on a post back and they cannot be created later in the page life cycle then the Page_Load method if you want their ViewState persisted and recovered)
Example code:
protected void Page_Load(object sender, EventArgs e)
{
var questionId = ViewState["QuestionTypeID"];
if(questionId == /* Value to create TextBox */) {
var txt = new TextBox { ID = "txt" };
placeHolder.Controls.Add(txt);
} else if(questionId == /* Value to create Calender */) {
var cal = new Calender { ID = "cal" };
placeHolder.Controls.Add(cal);
}
/* Once the controls are added they will be populated with the posted values */
}
P.S.
It's always a good idea with dynamic controls to specify the ID.
You can save the added controls to member variables and use them elsewhere (after they are assigned)
You can subscribe to their events and if the user posted a new value your method will be called
I have followed your advice and done the following:
1) Question Type is stored in view state in my server control.
2) on CreateChildControls now creates a new instance of my control and adds it to a place holder on the page.
My problem now is that things seem to fire in bit of an odd order:
1)On initial load of page, create child controls is fired and the RenderContents method of my server control fires.
2)A button is clicked to load a new contact, this triggers create child controls and RenderContents is fired.
3)details are entered and save is pressed, this triggers Create Child Controls but RenderContents is not triggered and a NullReferenceException is generated by trying to access my control to get the value out. (If i skip the code that access my controls, RenderContents is called and renders.
Seconly, another issue is that when I try an set a value (onDataBind) I try to access the Text box that has been generated in my server control and get another NullReferanceExeption
Thoughts?

Resources