Aspx get value of dynamically added text box - c#

I've added two text boxes dynamically on the aspx page.
I would like to get values from those two text boxes on the server side after postback (after Btn1 is clicked).
And here is my first problem - controls are not found.
I've tried to find controls with:
Page.FindControl("txt4");
What is wrong with this? Isn't the whole page posted back with all the controls in it?
My other question is - where in the code to get those values? In the Page_load event, before they are re-added? I guess when Btn1_Click event is triggered, those two controls are already re-added, so values from original postback are lost? (Page_load event is triggered before Btn1_Click).
I am really struggling with this.
It is much easier if controls are added through markup - they are directly accesible in code behind by theirs ID. But on the project that I work currently controls are mostly added dynamically, and a lot of them.
Code behind:
public partial class About : Page
{
protected void Page_Load(object sender, EventArgs e)
{
btn1.Click += Btn1_Click;
if(IsPostBack)
{
System.Web.UI.Control txt4_dynamic = Page.FindControl("txt4");
System.Web.UI.Control txt5_dynamic = Page.FindControl("txt5");
if(txt4_dynamic != null)
{
string str1 = ((TextBox)txt4_dynamic).Text;
}
if (txt5_dynamic != null)
{
string str1 = ((TextBox)txt5_dynamic).Text;
}
}
TextBox txt4 = new TextBox();
txt4.ClientIDMode = ClientIDMode.Static;
txt4.ID = "txt4";
TextBox txt5 = new TextBox();
txt5.ClientIDMode = ClientIDMode.Static;
txt5.ID = "txt5";
panel1.Controls.Add(txt4);
panel1.Controls.Add(txt5);
}
private void Btn1_Click(object sender, EventArgs e)
{
System.Web.UI.Control txt4_dynamic = Page.FindControl("txt4");
System.Web.UI.Control txt5_dynamic = Page.FindControl("txt5");
if (txt4_dynamic != null)
{
string str1 = ((TextBox)txt4_dynamic).Text;
}
if (txt5_dynamic != null)
{
string str1 = ((TextBox)txt5_dynamic).Text;
}
}
}
Markup:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:Button ID="btn1" runat="server" Text="Button" />
<asp:Panel ID="panel1" runat="server" ClientIDMode="Static">
</asp:Panel>
</asp:Content>
UPDATE:
I've updated my code with:
protected void Page_Init(object sender, EventArgs e)
{
if(IsPostBack)
{
TextBox txt4 = new TextBox();
txt4.ClientIDMode = ClientIDMode.Static;
txt4.ID = "txt4";
TextBox txt5 = new TextBox();
txt5.ClientIDMode = ClientIDMode.Static;
txt5.ID = "txt5";
panel1.Controls.Add(txt4);
panel1.Controls.Add(txt5);
string st1 = txt4.Text;
string st2 = txt5.Text;
System.Web.UI.Control txt4_dynamic = Page.FindControl("txt4");
System.Web.UI.Control txt5_dynamic = Page.FindControl("txt5");
if (txt4_dynamic != null)
{
string str1 = ((TextBox)txt4_dynamic).Text;
}
if (txt5_dynamic != null)
{
string str1 = ((TextBox)txt5_dynamic).Text;
}
}
}
I've checked the code in debugger - controls are added on postback, but values for st1, st2, txt4_dynamic and txt5_dynamic are still empty / null.
UPDATE 2:
There were two problems:
Finding control should be done with:
Page.Controls[0].FindControl("MainContent").FindControl("txt4");
Code above finds controls text only in controls events (and they are triggered after Page_Load).
So: Everything can stay as I originally posted - the only change needed is code for finding control, which must be in click event. If this same code is in Page_Load event, it will not work.

Please change the code to as below (basically move the dynamic control creation/addition to Page_Init):
public partial class About : Page
{
protected void Page_Init(object sender, EventArgs e)
{
TextBox txt4 = new TextBox();
txt4.ClientIDMode = ClientIDMode.Static;
txt4.ID = "txt4";
TextBox txt5 = new TextBox();
txt5.ClientIDMode = ClientIDMode.Static;
txt5.ID = "txt5";
panel1.Controls.Add(txt4);
panel1.Controls.Add(txt5);
}
protected void Page_Load(object sender, EventArgs e)
{
btn1.Click += Btn1_Click;
if (IsPostBack)
{
System.Web.UI.Control txt4_dynamic = Page.Controls[0].FindControl("MainContent").FindControl("txt4");
System.Web.UI.Control txt5_dynamic = Page.Controls[0].FindControl("MainContent").FindControl("txt5");
if (txt4_dynamic != null)
{
string str1 = ((TextBox)txt4_dynamic).Text;
}
if (txt5_dynamic != null)
{
string str1 = ((TextBox)txt5_dynamic).Text;
}
}
}
private void Btn1_Click(object sender, EventArgs e)
{
System.Web.UI.Control txt4_dynamic = Page.Controls[0].FindControl("MainContent").FindControl("txt4");
System.Web.UI.Control txt5_dynamic = Page.Controls[0].FindControl("MainContent").FindControl("txt5");
if (txt4_dynamic != null)
{
string str1 = ((TextBox)txt4_dynamic).Text;
}
if (txt5_dynamic != null)
{
string str1 = ((TextBox)txt5_dynamic).Text;
}
}
}
Control tree is created at server side on each postback. Since controls are added dynamically they need to be added on each postback, which you are already doing.
Reason for moving that code to Page_Init event is that, values posted from clientside are set in LoadPostData event which happens after Page_Init and before Page_Load.
When you have the code in Page_Init, by the time LoadPostData event happens control tree is already created and posted value is correctly set.
When you had the code in Page_Load, LoadPostData event happened even before the control was created and posted value was not set.

Related

After click on button how to retrieve dynamically textboxes value which is created in panel

**After creating a dynamic textboxes. once fill the value into textboxes. I am unable to retrieve the entered value from code behind. Please can you please help us. **
//Aspx controler//
<asp:panel id="pnlTextBoxes" runat="server" cssclass="Paneldetails">
//C# code//
TextBox txt = new TextBox();
txt.ID = results.data[i].name.ToString();
txt.CssClass = "tooltips";
txt.MaxLength = Convert.ToInt32(results.data[i].maxLength);
pnlTextBoxes.Controls.Add(txt);
///tried code to retrieve the textboxes values///
protected void btnAdd_Click(object sender, EventArgs e)
{
foreach (Control ctrl in pnlTextBoxes.Controls)
{
if (ctrl is TextBox)
{
DSF.name = ((TextBox)ctrl).ID;
DSF.value = ((TextBox)ctrl).Text;
summ.Add(DSF);
}
}

Dynamically created linkbuttons' common event not firing

Whenever DropDownList SelectedIndexChanged, I am adding LinkButtons as ul-li list in codebehind. Each linkbuttons were assigned with IDs and a common Click event. Problem is code in Click event is not executed or maybe event is not triggered. My code below: [Edit] I tried like this as suggested in other posts (dynamically created list of link buttons, link buttons not posting back)
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
populate();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
populate();
}
void populate()
{
HtmlGenericControl ulList = new HtmlGenericControl("ul");
panel.Controls.Add(ulList);
foreach (DataRow dr in drc)
{
HtmlGenericControl liList = new HtmlGenericControl("li");
ulList.Controls.Add(liList);
var lnk = new LinkButton();
lnk.ID = dr["col1"].ToString();
lnk.Text = dr["col1"].ToString();
lnk.Click += Clicked;
liList.Controls.Add(lnk);
}
}
private void Clicked(object sender, EventArgs e)
{
var btn = (LinkButton)sender;
label1.Text = btn.ID.ToString();
}
Im missing something. Any help please.
Here the issue is with the ViewState. When the selected index of the dropdownlist changes there is a postback which takes place and the previous state is lost, so at this point you have to maintain the state of the controls.
Now in your code actually the state of the control is lost and so the click event does not fire. So the solution is to maintain the state of the controls.
The Below is a working example, you can just paste it and try.
This is my page load.
protected void Page_Load(object sender, EventArgs e)
{
for (var i = 0; i < LinkButtonNumber; i++)
AddLinkButton(i);
}
Similarly you have to maintain the state of the previously added control like this.
private int LinkButtonNumber
{
get
{
var number = ViewState["linkButtonNumber"];
return (number == null) ? 0 : (int)number;
}
set
{
ViewState["linkButtonNumber"] = value;
}
}
The below is my SelectedIndexChanged Event for the DropDownList
protected void Example_SelectedIndexChanged(object sender, EventArgs e)
{
AddLinkButton(LinkButtonNumber);
LinkButtonNumber++;
}
I have a function which dynamically creates the controls, which is called on the page load and on SelectedIndexChanged.
private void AddLinkButton(int index)
{
LinkButton linkbutton = new LinkButton { ID = string.Concat("txtDomain", index) };
linkbutton.ClientIDMode = ClientIDMode.Static;
linkbutton.Text = "Link Button ";
linkbutton.Click += linkbutton_Click;
PanelDomain.Controls.Add(linkbutton);
PanelDomain.Controls.Add(new LiteralControl("<br />"));
}
And this is the Click event for the LinkButton
void linkbutton_Click(object sender, EventArgs e)
{
//You logic here
}
I solved it using brute code lol.
Since controls' event were not bound on postback then we recreate them on postback. So in my Page_Load I called the module that re-creates the controls, thus binding them to corresponding event. This works, but...
Re-creating these controls create duplicates (Multiple Controls with same ID were found) and you will get into trouble in instances of finding a control by ID like using panel.FindControl.
To remedy this scenario, I put a check if same control ID already existed before recreating them, and voila! It works.
protected void Page_Load(object sender, EventArgs e)
{
populate();
}
void populate()
{
HtmlGenericControl ulList = new HtmlGenericControl("ul");
panel.Controls.Add(ulList);
foreach (DataRow dr in drc)
{
HtmlGenericControl liList = new HtmlGenericControl("li");
ulList.Controls.Add(liList);
if (liList.FindControl(dr["col1"].ToString()) == null)
{
var lnk = new LinkButton();
lnk.ID = dr["col1"].ToString();
lnk.Text = dr["col1"].ToString();
lnk.Click += Clicked;
liList.Controls.Add(lnk);
}
}
}

Dynamically created LinkButton OnClick Event not firing on PostBack

I am quite new to ASP and I have been stuck on an issue for about a week. The issue is probably something to do with the Asp Page Life Cycle but I am unable to find how this can be resolved. The issue is that skipto(..) is never called when I click the LinkButton (that were created on first Page Load), which means the LinkButtons are not rendered.
Sample Code below:
// Code Behind
protected void Page_Load(object sender, EventArgs e)
{
loadData();
if (!Page.IsPostBack)
{
skiptof();
}
}
public void loadData() {
// Loads from database
}
public void skipto(object sender, EventArgs e)
{
LinkButton btn = sender as LinkButton;
if (btn != null)
{
if (btn.CommandArgument != null && btn.CommandArgument != "0")
{
int currPage = 1;
int.TryParse(btn.CommandArgument, out currPage);
skiptof(currPage);
}
}
}
public void skiptof(int currPage = 1)
{
int lastPage = // calculate from LoadData()
string pageDisabled = "";
// pages
HtmlGenericControl ul = new HtmlGenericControl("ul");
while (pageCount <= lastPage)
{
// Disable the current page
pageDisabled = pageCount == currPage ? " class=\"disabled\"" : "";
HtmlGenericControl pagesli = new HtmlGenericControl("li");
if (pageDisabled != "")
{
pagesli.Attributes.Add("class", "disabled");
}
LinkButton pagesPageLink = new LinkButton();
pagesPageLink.Click += new EventHandler(skipto);
pagesPageLink.CommandArgument = pageCount.ToString();
pagesPageLink.Text = pageCount.ToString();
pagesli.Controls.Add(pagesPageLink);
ul.Controls.Add(pagesli);
pageCount += 1;
}
pagination.Controls.Add(ul);
}
// page
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<asp:UpdatePanel runat="server" id="UpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<div id="details" runat="server"></div>
<div class="pagination text-center" id="pagination" runat="server"></div>
</ContentTemplate>
</asp:UpdatePanel>
Your problem is:
You didn't bind the data again on postback, I've modified your code a little bit, there are several problems:
in the method skipof:
public void skiptof(int currPage = 1) {
//Clear the controls here then add them again
pagination.Controls.Clear();
int lastPage = // calculate from LoadData()
string pageDisabled = "";
HtmlGenericControl ul = new HtmlGenericControl("ul");
while (pageCount <= lastPage) {
// Disable the current page
pageDisabled = pageCount == currPage ? " class=\"disabled\"" : "";
HtmlGenericControl pagesli = new HtmlGenericControl("li");
if (pageDisabled != "") {
pagesli.Attributes.Add("class", "disabled");
}
LinkButton pagesPageLink = new LinkButton();
// you can directly assign the method to be called here, there is no need to create a new EventHandler
pagesPageLink.Click += PagesPageLink_Click;
pagesPageLink.CommandArgument = pageCount.ToString();
pagesPageLink.Text = pageCount.ToString();
pagesli.Controls.Add(pagesPageLink);
ul.Controls.Add(pagesli);
pageCount += 1;
}
pagination.Controls.Add(ul);
}
You didn't bind the data again in postback, so I modified it:
Page Load:
protected void Page_Load(object sender, EventArgs e) {
//Remove the Page.IsPostBack checking
skiptof();
}
Please take note that the controls you added dynamically will be cleared and you have to add it again on postback to avoid data lost.
Then you'll be able to get the value on PagesPageLink_Click event:
The whole sample is here:
http://pastie.org/10503291

how to create event handler for dynamic drop down list in c#

I have created a dynamic grid view using Itemplate .now i have also created a dynamic drop down list in the grid . how to create a event handler for on selectedindexchange .
i created a slectedindexchange event but it didnt work .the control never passes to the event ?
what to do create a event handler
public class DynamicGridViewTextTemplate : ITemplate
{
string _ColName;
DataControlRowType _rowType;
int _Count;
details Details1 = new details();
public DynamicGridViewTextTemplate(string ColName, DataControlRowType RowType)
{
_ColName = ColName;
_rowType = RowType;
}
public DynamicGridViewTextTemplate(DataControlRowType RowType, int ArticleCount)
{
_rowType = RowType;
_Count = ArticleCount;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (_rowType)
{
case DataControlRowType.Header:
Literal lc = new Literal();
lc.Text = "<b>" + _ColName + "</b>";
DropDownList ddl = new DropDownList();
ddl.AutoPostBack = true;
ddl.SelectedIndexChanged += new EventHandler(this.ddl_SelIndexChanged);
container.Controls.Add(lc);
container.Controls.Add(ddl);
break;
case DataControlRowType.DataRow:
//Label lbl = new Label();
//lbl.DataBinding += new EventHandler(this.lbl_DataBind);
LinkButton lb = new LinkButton();
lb.DataBinding += new EventHandler(this.lbl_DataBind);
lb.OnClientClick +=new EventHandler(this.lb_Click);
//lbl.Controls.Add(lb);
container.Controls.Add(lb);
break;
case DataControlRowType.Footer:
Literal flc = new Literal();
flc.Text = "<b>Total No of Articles:" + _Count + "</b>";
container.Controls.Add(flc);
break;
default:
break;
}
}
private void lb_Click(Object sender, EventArgs e)
{
details1.lbl_Click(sender, e);
}
private void lbl_DataBind(Object sender, EventArgs e)
{
//Label lbl = (Label)sender;
LinkButton lbl = (LinkButton)sender;
GridViewRow row = (GridViewRow)lbl.NamingContainer;
lbl.Text =DataBinder.Eval(row.DataItem, _ColName).ToString();
}
public void ddl_SelIndexChanged(Object sender, EventArgs e)
{
Details1.ddlFilter_SelectedIndexChanged(sender,e);
}
}
you can declare you selectedindexchanged event like this:
ddlFilter.SelectedIndexChanged += new EventHandler(ddl2_SelectedIndexChanged);
ddlFilter.AutoPostBack = true;
void ddlFilter_SelectedIndexChanged(object sender, EventArgs e)
{
//your code
}
The reason your event wasn't called is the AutoPostBack=true field. If you don't set it to true your selectedIndexChanged event will never be called.
Whenever I create a new Control in an ASP web page I follow this boiler plate (note that I added some example controls so it's not a "clean" boiler plate):
namespace Components {
[ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")]
public class MyControl : WebControl, INamingContainer {
// todo: add controls that are created dynamically
private GridView gridView;
public MyControl () {
Initialize();
}
[Browsable(false)]
public override ControlCollection Controls {
get { EnsureChildControls(); return base.Controls; }
}
protected override void OnLoad(EventArgs e) {
// todo: attach event listeners for instance
base.OnLoad(e);
}
protected override void CreateChildControls() {
Initialize();
}
protected override void Render(HtmlTextWriter writer) {
if (DesignMode) {
// If special design mode rendering
return;
}
base.Render(writer);
}
/// This is where the controls are created
private void Initialize() {
base.Controls.Clear();
// todo: Create all controls to add, even those "added later"
// if something is generated but should not be shown,
// set its Visible to false until its state is changed
Label exampleLabel = new Label();
exampleLabel.Visible = false; // like so
if (gridView == null) { gridView = new GridView(); }
base.Controls.Add(exampleLabel);
base.Controls.Add(gridView);
}
}
}
Now, if you create your dynamic drop down in Initialize and add it to your Controls collection every time but only set its Visibility to true when you want it to show, your event should be triggered, since the id's of your controls should be the same between postbacks.
Dynamic control's event to occure, it is required that it should be created and event assigned in page_load event or during the page_load event occures. Control's event will fire after Page_Load event completes. If control is not recreated in page_load event, event will not bind to the control and will not fire.
I had the same problem and I was creating the dynamic ddl inside (!Page.IsPostBack). When i moved the creation outside the (!Page.IsPostBack) it worked fine.
You must create your elements outside the (!Page.IsPostBack) like MUG4N said and it should work fine.
Thats how I did it with a Dropdownlist generated out of a ComboBox
code :
setConnectionToolStripMenuItem.DropDownItems.AddRange(toolStripComboBoxConnections.Items.Cast<string>().Select(text => new ToolStripMenuItem(text, null, new EventHandler(DropDown_Click_Event))).ToArray());

ASP.NET dynamically created textbox doesn't change value

I have the following issue:
I create a TextBox dynamically in my web page, its value is "initialVal" in the beginning.
Now I need to make a postback (not callback) to the server, and during this operation, I need to compute/change the value of my textbox to other value.
Here's an example:
protected void Page_Load(object sender, EventArgs e)
{
TextBox txtBox = new TextBox();
txtBox.ID = "newButton";
form1.Controls.Add(txtBox);
txtBox.Text = "initialVal";
if (IsPostBack && Session["change"] == null)
{
txtBox.Text = "change";
Session["change"] = true;
}
}
The problem: even if I change the value via code, the textbox will keep the text "initialVal". I feel this is something related to the view state, but I don't understand.
Coudl anyone please help me here?
Thanks.
Everytime you load the page it is running this:
txtBox.Text = "initialVal";
You should wrap this in a check for postback:
if (!Page.IsPostback)
{
txtBox.Text = "initialVal";
}
That said, onLoad is the wrong event to do the creation, for it to be valid in the early enough in the page lifecycle, use OnInit.
See this article on MSDN.
Here is the final code from #user2890888:
public partial class WebForm1 : System.Web.UI.Page
{
TextBox txtBox = null;
protected void Page_Init(object sender, EventArgs e)
{
txtBox = new TextBox();
txtBox.ID = "newButton";
form1.Controls.Add(txtBox);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
txtBox.Text = "initialVal";
}
if (IsPostBack && Session["change"] == null)
{
txtBox.Text = "change";
Session["change"] = true;
}
}
}
Create your dynamic textbox creation in !IsPostBack
protected void Page_Load(object sender, EventArgs e)
{
if(!isPostBack){
TextBox txtBox = new TextBox();
txtBox.ID = "newButton";
form1.Controls.Add(txtBox);
txtBox.Text = "initialVal";
}
if (IsPostBack && Session["change"] == null)
{
txtBox.Text = "change";
Session["change"] = true;
}
}
Thanks and let me know if your issue still pending
Find the TextBox and use it
TextBox txtBox = (TextBox)FindControl("txtBox");
txtBox.Text = "change";
Even now you are having issue and your textBox is not getting the value you needed.
Store your new value for TEXTBOX in a hiddenfield.
I mean ,
if (IsPostBack && Session["change"] == null)
{
hiddenfield1.value = "change";
}
and later in your page script, you can assign back the value in this hiddenfield1 to textbox.
$(document).ready(
{
$('#txtBoxID').value=$('#hiddenfield1').value;
}
);

Categories