Get value from a user control that add dynamically in asp.net - c#

I wanted to add some controls by clicking on the button. and when click again, this controls repeated. and then by click to another button save value from all controls.
so I use a usercontrol(FilterParameters ) that have this controls :
<div class="main">
<asp:label ID="FilterByParam" runat="server" Text="filter" ></asp:label>
<asp:TextBox ID="txtFilter" runat="server" CssClass="NormalTextBox" Width="200px"></asp:TextBox>
</div>
<div class="main">
<asp:label ID="FilterRule" runat="server" Text="Rule"></asp:label>
<asp:TextBox ID="txtRule" runat="server" Width="330px" Height="50px" TextMode="MultiLine"></asp:TextBox>
</div>
and I use this code in my code to load this user control( I add a placeholder to add this usercontrol) :
protected void lnkAddNew_Click(object sender, EventArgs e)
{
int count = 0;
if (ViewState["count"] != null)
{
count = (int)ViewState["count"];
}
count++;
ViewState["count"] = count;
CreateControls();
}
private void CreateControls()
{
int count = 0;
if (ViewState["count"] != null)
{
count = (int)ViewState["count"];
}
while (placeholder.Controls.Count < count)
{
Common.FilterParameters fp = (Common.FilterParameters)LoadControl("~/Common/FilterParameters.ascx");
fp.ID = "fp" + placeholder.Controls.Count.ToString();
placeholder.Controls.Add(fp);
}
}
This control load carefully. but I have problem by save data from this controls. I use this code but didn't work. ( placeholder.controls.count is always 0)
private void SaveFilters()
{
int count = 0;
if (ViewState["count"] != null)
{
count = (int)ViewState["count"];
}
string str=string.Empty;
for (int i = 0; i <= placeholder.Controls.Count; i++)
{
Common.FilterParameters fp = (Common.FilterParameters)placeholder.FindControl("fp"+i.ToString());
if(fp!=null)
{
string param = fp.filterparamText;
string rule = fp.RuleText;
str+="{"+param+"+"+rule+"}";
}
}
if(!string.IsNullOrEmpty(str))
{
save(str);
}
}
how can I get data from this user control?

I assume your "SaveFilters" method is being called when the webform posts back, either from the Page Load event or from the event that caused the postback (eg a button click event).
You need to reload all of your dynamic controls on every postback if you want to be able to read their values. The typical pattern is to add dynamic controls from the Page Init event. The Asp.Net runtime assigns values to the controls from the form after Page Init. You can read those values from the Page Load event or from the event that caused the postback (eg a button click event).
If you do not re-add the dynamic controls the Asp.net runtime has nowhere to place the values from the form, and so those values are lost.
So, for dynamic controls:
1. Load them in the Page Init event every time the page posts back.
2. Read values from them in the Page Load event or in the event that caused the postback (eg a button click event).

Related

System.Web.UI.WebControls.Button click event not firing

In my C# code I have function to dynamically create buttons
private Button createPageButton(string id, string text, int navTo = 0)
{
Button btn = new Button();
btn.ID = id;
btn.Text = text;
btn.Click += new EventHandler(btnNavigate_To_Page);
return btn;
}
Which gets setup like this:
C#:
public void someMethod()
{
Button btnPage_First = createPageButton("btnFirst_Page", "First", 1);
panelNavPageButtons.Controls.Add(btnPage_First);
}
aspx:
<asp:Panel ID="panelPageNavButtons" CssClass="pageNavBtns" runat="server"></asp:Panel>
Problem: The btnNavigate_To_Page event does not fire. The createPageButton method is not called within Page_Load but if I include an asp button in the panel (see below) then any additional button I add on the server side works properly
<asp:Panel ID="panelPageNavButtons" CssClass="pageNavBtns" runat="server">
<asp:Button ID="btnPage_Prev" runat="server" OnClick="btnNavigate_To_Page" />
</asp:Panel>
I would like to set up all the buttons dynamically without including any reference to btnNavigate_To_Page in the .aspx file
You have to call someMethod method inside either Init or Load event.
The reason is dynamically created controls are not in the control tree, so you have to reload them on every post back with same id.
protected void Page_Init(object sender, EventArgs e)
{
someMethod();
}

Label Does Not Change After TextBox OnTextChanged Event ASP.NET

I have a username TextBox and a Label which should update to (V or X) when the TextBox text is changed. The label is updated only if, for example I press a button which automatically refreshes the page.
Here is the code:
<asp:TextBox ID="username" runat="server" OnTextChanged="checkUsername" Width="80%"></asp:TextBox>
<asp:Label ID="usernameCheck" runat="server" CssClass="checkL"></asp:Label>
And the aspx.cs
protected void checkUsername(object sender, EventArgs e)
{
if (username.Text.Length < 3 || username.Text.Length > 15)
{
//---Label = X (in red)
usernameCheck.Text = "\u2715";
}
else
{
if (myBl.checkUsername(Convert.ToString(username)))
{
//---Label = X (in red)
usernameCheck.Text = "\u2715";
}
else
{
//---Label = V (in green)
usernameCheck.Text = "\u2713";
}
}
}
Thanks for any help.
You need to add AutoPostBack="true" to your TextBox. This will cause it to post back and for that server side event to fire.
There are much better ways of doing what you are trying to accomplish though, most of which do not require a full page postback. I would try to make an AJAX call using the javascript change event, and using something like a callback method.

Checkbox List evaluating all checkmarks as false

I have a simple checkbox list and I'm using a for statement to retrieve the selected values into one string. This has to be simple, but everything is returning false when it evaluates if it is selected.
ASP Code
<asp:CheckBoxList runat="server" ID="ckblInterests" ClientIDMode="Static" RepeatColumns="2" />
ASP.NET Code:
string interests = "";
for (int i = 0; i < ckblInterests.Items.Count; i++)
{
if (ckblInterests.Items[i].Selected)
{
interests += ckblInterests.Items[i].Value + ", ";
}
}
}
The inside if statement evaluates as false each time it loops through. It does count 10 items in the list correctly. I'm stumped at something so simple. Can someone help me identify what might be causing the if statement to return false?
You have code that's dynamically adding the checkboxes to the list on page load (or some other event). This is resulting in the state of those checkboxes being cleared and re-added on each postback. Your page load should probably have an if(!page.ispostback) around that section so that you aren't clearing the content.
With the Following Code (Mostly yours)
Aspx
<div>
<asp:CheckBoxList runat="server" ID="ckblInterests" ClientIDMode="Static" RepeatColumns="2">
<asp:ListItem>Awesome</asp:ListItem>
<asp:ListItem>Tasty</asp:ListItem>
<asp:ListItem>Terrible</asp:ListItem>
</asp:CheckBoxList>
</div>
<asp:Button runat="server" ID="test" OnClick="test_Click" />
<asp:Label runat="server" ID="label"></asp:Label>
c#
protected void test_Click(object sender, EventArgs e)
{
string interests = "";
for (int i = 0; i < ckblInterests.Items.Count; i++)
{
if (ckblInterests.Items[i].Selected)
{
interests += ckblInterests.Items[i].Value + ", ";
}
}
this.label.Text = interests;
}
I was able to produce the following. This is of course after clicking the button.
Are you binding to a datasource that you have not mentioned?
make sure while binding the checkboxlist in page load you have set this check if (!Page.IsPostBack) { ...bind your data }
this should do the trick
I think you need to check the CHECKED property, not SELECTED.

CheckBoxList gets cleared on button click

I am creating a custom view in a SharePoint visual Web Part using ASP.NET (Visual C#) and have a CheckBoxList, and a button.
MarkUp for the List & Button:
<td>
<asp:checkboxlist ID="cblYearLst" runat="server" EnableViewState="true" />
</td>
<td>
<asp:Button ID="btnRefineSearch" Text="Refine Search" runat="server" />
</td>
I add items to the CheckBoxList on PreRender:
if (!IsPostBack)
{
if (LstYears != null)
{
for (int i = 0; i < LstYears.Count(); i++)
{
cblYearLst.Items.Add(new ListItem(LstYears[i], LstYears[i]));
}
}
}
And I call the event Handler for the button on Page_Load:
btnRefineSearch.Click += new EventHandler(this.btnRefineSearch_Click);
All of the CheckBox list-items do not stay selected after the button is clicked. I can retrieve the selected values, but they won't display as selected. When I add the Click event handler for the button in the pre-render event, the data is displayed appropriately but the selected values can no longer be retrieved by my Click event.
Any ideas on what might be causing this behaviour??
Did you try moving the binding of the checkboxlist into the page_load instead of pre_render? Just an idea because it seems like the page is losing selections on postback and you are regenerating the options each time.
UPDATE: I created a quick page and this works correctly. Do you have your viewstate turned off for the entire page in your page directive, or possibly in the web.config? I see you have it enabled on the checkboxlist but maybe there is a global setting throwing you off.
protected void Page_Load(object sender, EventArgs e)
{
btnRefineSearch.Click += new EventHandler(this.btnRefineSearch_Click);
List<string> LstYears = new List<string>();
LstYears.Add("one");
LstYears.Add("two");
LstYears.Add("three");
LstYears.Add("four");
if (!IsPostBack)
{
if (LstYears != null)
{
for (int i = 0; i < LstYears.Count; i++)
{
cblYearLst.Items.Add(new ListItem(LstYears[i], LstYears[i]));
}
}
}
}
private void btnRefineSearch_Click(object sender, EventArgs args)
{
Response.Write(cblYearLst.SelectedValue);
}
I figured out the issue, since I have AutoEventWireUp set to true as Keenan has suggested it should all work if I do it in the page_load.
The problem was that Page_Load was being called twice, and I discovered that this was because I was redirecting the user to the same URL with QueryString parameters. After I made the much needed changes, my code works very well.
+1 Keenan for your help and thank you (#jfmags) for tipping me off by telling me you think it is something else.
:D

Persistent dynamic control in ASP.Net

<asp:Button onclick="Some_event" Text="Add TextBox" ID="id1" runat="server" />
//once clicked:
<asp:TextBox ID="txt1" ......></asp:TextBox>
//when clicked again:
<asp:TextBox ID="txt1" ......></asp:TextBox>
<asp:TextBox ID="txt2" ......></asp:TextBox>
//and so on...
Is there a way to create dynamic controls which will persist even after the postback? In other words, when the user clicks on the button, a new textbox will be generated and when clicks again the first one will remain while a second one will be generated. How can I do this using asp.net ? I know that if I can create the controls in the page_init event then they will persist but I dont know if it possible to handle a button click before the page_init occurs, therefore there must be another way.
Yes, this is possible. One way to do this using purely ASP.NET (which seems like what you're asking for) would be to keep a count of the TextBox controls that you have added (storing that value in the ViewState) and recreate the TextBox controls in the Page_Load event. Of course, nowadays most people would probably use Javascript or jQuery to handle this task client side, but I put together a quick example to demonstrate how it works with postbacks:
Front page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicControls.aspx.cs" Inherits="MyAspnetApp.DynamicControls" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAddTextBox" runat="server" Text="Add" OnClick="btnAddTextBox_Click" />
<asp:Button ID="btnWriteValues" runat="server" Text="Write" OnClick="btnWriteValues_Click" />
<asp:PlaceHolder ID="phControls" runat="server" />
</div>
</form>
</body>
</html>
Code behind:
using System;
using System.Web.UI.WebControls;
namespace MyAspnetApp
{
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Recreate textbox controls
if(Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var txt = new TextBox {ID = string.Concat("txtDynamic", index)};
txt.Style.Add("display", "block");
phControls.Controls.Add(txt);
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var textBox = control as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
}
Since you are recreating the controls on each postback, the values entered into the textboxes will be persisted across each postback. I added btnWriteValues_Click to quickly demonstrate how to read the values out of the textboxes.
EDIT
I updated the example to add a Panel containing a TextBox and a Remove Button. The trick here is that the Remove button does not delete the container Panel, it merely makes it not Visible. This is done so that all of the control IDs remain the same, so the data entered stays with each TextBox. If we were to remove the TextBox entirely, the data after the TextBox that was removed would shift down one TextBox on the next postback (just to explain this a little more clearly, if we have txt1, txt2 and txt3, and we remove txt2, on the next postback we'll create two textboxes, txt1 and txt2, and the value that was in txt3 would be lost).
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var panel = control as Panel;
if (panel == null || !panel.Visible) continue;
foreach (var control2 in panel.Controls)
{
var textBox = control2 as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var panel = new Panel();
panel.Controls.Add(new TextBox {ID = string.Concat("txtDynamic", index)});
var btn = new Button { Text="Remove" };
btn.Click += btnRemove_Click;
panel.Controls.Add(btn);
phControls.Controls.Add(panel);
}
private void btnRemove_Click(object sender, EventArgs e)
{
var btnRemove = sender as Button;
if (btnRemove == null) return;
btnRemove.Parent.Visible = false;
}
}
I read an article by Scott Mitchell that explains that ViewState only persists changed control state across post-back, and not the actual controls themselves. I did not have your exact scenario, but a project I was working on required dynamically added user controls and I had to add them on every postback. In that case, it is still useful to create them in Init so that they can retain their state. Here is the link: Understanding ASP.NET View State. Check section “View State and Dynamically Added Controls”.
You may have to keep track of all the controls that you are adding (in session state for example) and re-create them on post back. I just did a small test where I keep a List<string> of all the Textbox ids in Session. On postback, I recreate all the textboxes.

Categories