I'm creating a to-do list application. Items in the list are loaded from a db and displayed dynamically via code-behind (c#) and this is working fine. You can click a dynamically created ImageButton to check an item off the list and the db is updating
properly. So far so good.
The problem comes when I want to allow users to edit the text of a list item directly in line with the text. I have a dynamically created "Edit" next to each item which, when clicked, puts the text of the item into a TextBox rather than a Label as it is
initially generated. A "Save" button also appears. This all works fine. But I can't figure out how to capture the text in the TextBox once the user has changed it and clicks "Save". I think it is a matter of using the correct page life cycle event, but
I can't seem to figure it out. The text I'm trying to save always reverts to its previous value.
Any ideas? I'm perfectly willing to use workarounds, like storing the text in an invisible control or something like that.
Code to generate TextBox and Save button is called from Page_PreInit:
LinkButton btnEditItemSave = new LinkButton();
TextBox txtEditTitle = new TextBox();
btnEditItemSave.Text = "Save";
btnEditItemSave.CommandArgument += item1.ID.ToString();
btnEditItemSave.Command += new CommandEventHandler(Edit_Item_Save);
btnEditItemSave.ID = "btnEditItemSave" + item1.ID.ToString();
txtEditTitle.ID = "txtEditTitle1";
I should probably point out that the db update is test code. I'm trying to just update a known record (ID = 2) for now. Just update something! Anything! :-)
In order for you to access dynamically created controls, you need to recreate for each subsequent request. That includes the LinkButton control, as the Command event can't be executed unless the control exists and has the event handler assigned to the event.
Furthermore, the text box needs to be created before the LoadViewState method is called, so that the text property can be updated, which means that it needs to be created in Page_PreInit or Page_Init.
That makes complete sense. Unfortunately it kind of blows up my whole flow, but I'll say I'm back to square 2 and not all the way to square 1. Thanks for your help!
Thanks again Steven, and in case anyone might benefit from this, here's how I worked around my particular problem after Steven showed my what I needed to do.
In the event handling the Edit button, I added a string to ViewState that contained the record ID of the item I wanted to edit, like this:
ViewState["EditThisRecord"] = e.CommandArgument;
Then I used the Page_SaveStateComplete event to write that value to a Session variable, like this:
protected void Page_SaveStateComplete(object sender, EventArgs e)
{
//Save viewstate variables into session variables to be used in Page_Init
if (ViewState["EditThisRecord"] != null)
{
Session["RecordIDOfEditItem"] = ViewState["EditThisRecord"].ToString();
}
}
In that way, I was able to pass the record ID from Page_SaveStateComplete to Page_Init. There may be a cleaner way to do this, but I don't know it! After I had the record ID in Page_Init, I simply passed it into the function that was building the dynamic
controls and the rest worked as expected. Just make sure you set the ViewState variable you created back to null in the Save button event, otherwise it hangs around and causes weirdness.
In that way, I was able to pass the record ID from Page_SaveStateComplete to Page_Init. There may be a cleaner way to do this, but I don't know it! After I had the record ID in Page_Init, I simply passed it into the function that was building the dynamic
controls and the rest worked as expected. Just make sure you set the ViewState variable you created back to null in the Save button event, otherwise it hangs around and causes weirdness.
Why not just assign directly to Session in the event handler and don't bother with ViewState? :)
Straeken
Member
19 Points
26 Posts
Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:08 PM|LINK
I'm creating a to-do list application. Items in the list are loaded from a db and displayed dynamically via code-behind (c#) and this is working fine. You can click a dynamically created ImageButton to check an item off the list and the db is updating properly. So far so good.
The problem comes when I want to allow users to edit the text of a list item directly in line with the text. I have a dynamically created "Edit" next to each item which, when clicked, puts the text of the item into a TextBox rather than a Label as it is initially generated. A "Save" button also appears. This all works fine. But I can't figure out how to capture the text in the TextBox once the user has changed it and clicks "Save". I think it is a matter of using the correct page life cycle event, but I can't seem to figure it out. The text I'm trying to save always reverts to its previous value.
Any ideas? I'm perfectly willing to use workarounds, like storing the text in an invisible control or something like that.
Code to generate TextBox and Save button is called from Page_PreInit:
LinkButton btnEditItemSave = new LinkButton(); TextBox txtEditTitle = new TextBox(); btnEditItemSave.Text = "Save"; btnEditItemSave.CommandArgument += item1.ID.ToString(); btnEditItemSave.Command += new CommandEventHandler(Edit_Item_Save); btnEditItemSave.ID = "btnEditItemSave" + item1.ID.ToString(); txtEditTitle.ID = "txtEditTitle1";Code to actually save the item:
protected void Edit_Item_Save(object sender, CommandEventArgs e) { TextBox txtMyTitle = (TextBox) phThisList.FindControl("txtEditTitle1"); string myTitle = txtMyTitle.Text; //code to update database with myTitle... }stevenbey
All-Star
16526 Points
3378 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:26 PM|LINK
Are you adding the text box to the phThisList control during postback?
http://stevenbey.com
Recursion: see Recursion
Straeken
Member
19 Points
26 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:28 PM|LINK
Yes.
stevenbey
All-Star
16526 Points
3378 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:28 PM|LINK
Sorry, wasn't clear:
Are you adding the text box to the phThisList control during postback that was triggered by the Save button?
http://stevenbey.com
Recursion: see Recursion
Straeken
Member
19 Points
26 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:32 PM|LINK
No. Here is the entire event, in case I've left out something critical:
protected void Edit_Item_Save(object sender, CommandEventArgs e) { int listID = Convert.ToInt16(Request.QueryString["id"]); TextBox txtMyTitle = (TextBox) phThisList.FindControl("txtEditTitle1"); TextBox txtMyID = (TextBox) phThisList.FindControl("txtEditID1"); string myTitle = txtMyTitle.Text; int myID = Convert.ToInt16(txtMyID.Text); AttendanceDataContext db1 = new AttendanceDataContext(); var upd = db1.ToDoListItems.SingleOrDefault (x => x.ID == 2); upd.Title = "something else"; db1.SubmitChanges(); }Straeken
Member
19 Points
26 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:36 PM|LINK
I should probably point out that the db update is test code. I'm trying to just update a known record (ID = 2) for now. Just update something! Anything! :-)
stevenbey
All-Star
16526 Points
3378 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 04:41 PM|LINK
In order for you to access dynamically created controls, you need to recreate for each subsequent request. That includes the LinkButton control, as the Command event can't be executed unless the control exists and has the event handler assigned to the event. Furthermore, the text box needs to be created before the LoadViewState method is called, so that the text property can be updated, which means that it needs to be created in Page_PreInit or Page_Init.
http://stevenbey.com
Recursion: see Recursion
Straeken
Member
19 Points
26 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 05:23 PM|LINK
That makes complete sense. Unfortunately it kind of blows up my whole flow, but I'll say I'm back to square 2 and not all the way to square 1. Thanks for your help!
Straeken
Member
19 Points
26 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 13, 2012 07:14 PM|LINK
Thanks again Steven, and in case anyone might benefit from this, here's how I worked around my particular problem after Steven showed my what I needed to do.
In the event handling the Edit button, I added a string to ViewState that contained the record ID of the item I wanted to edit, like this:
Then I used the Page_SaveStateComplete event to write that value to a Session variable, like this:
protected void Page_SaveStateComplete(object sender, EventArgs e) { //Save viewstate variables into session variables to be used in Page_Init if (ViewState["EditThisRecord"] != null) { Session["RecordIDOfEditItem"] = ViewState["EditThisRecord"].ToString(); } }In that way, I was able to pass the record ID from Page_SaveStateComplete to Page_Init. There may be a cleaner way to do this, but I don't know it! After I had the record ID in Page_Init, I simply passed it into the function that was building the dynamic controls and the rest worked as expected. Just make sure you set the ViewState variable you created back to null in the Save button event, otherwise it hangs around and causes weirdness.
stevenbey
All-Star
16526 Points
3378 Posts
Re: Accessing dynamically created TextBox after PostBack
Feb 14, 2012 10:12 AM|LINK
Why not just assign directly to Session in the event handler and don't bother with ViewState? :)
http://stevenbey.com
Recursion: see Recursion