programmatically added click event in user control won't fire - asp.net

I'm having issues getting the click event for a button contained within a programmatically added user control to fire. I understand that the event must be wired up each time a new user control is added, and I'm pretty sure I'm doing that, but still nothing. The click event for the button works fine for the first user control, which is not added programmatically. Here's the markup for the user control....
<asp:Panel ID="pnlAddressForm" runat="server">
<asp:Label ID="lblStreet" runat="server" Text="Street Address"></asp:Label>
<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblZip" runat="server" Text="Zip"></asp:Label>
<asp:TextBox ID="txtZip" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="btnRemoveAddress" runat="server" Text="Remove Address" OnClick="btnRemoveAddress_Click" />
</asp:Panel>
...and here's the markup for the main page...
<form id="form1" runat="server">
<div>
<My:FormUserControl runat="server" ID="myFormUserControl" />
<br /><br />
<hr />
<My:AddressUserControl runat="server" ID="myAddressUserControl" />
<br /><br />
<asp:PlaceHolder ID="phAddresses" runat="server"></asp:PlaceHolder>
<br /><br />
<asp:Button ID="btnAddAddress" runat="server" Text="Add Another Address" OnClick="btnAddAddress_Click" />
</div>
<br /><br />
<hr />
<asp:Button ID="btnSubmit" runat="server" Text="Create PDF" OnClick="btnSubmit_Click" />
</form>
..as you can see it already contains one AddressUserControl declaratively. All subsequent AddressUserControls are added to phAddresses once btnAddAddress is clicked. AddressUserControls are added this way in the code behind...
private static List<AddressUserControl> addresses = new List<AddressUserControl>();
protected void Page_PreInit(object sender, EventArgs e)
{
int addressCount = 0;
foreach (AddressUserControl aCntrl in addresses)
{
Literal ltlSpace = new Literal();
ltlSpace.Text = "<br /><br />";
phAddresses.Controls.Add(aCntrl);
phAddresses.Controls.Add(ltlSpace);
addressCount++;
}
}
When btnAddAddress is click this event handler runs...
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addresses.Count + 1;
addressUserControlButton.Click += new EventHandler(addressUserControlButton_Click);
addresses.Add(aCntrl);
}
...and here's the addressUserControlButton event handler. This never runs, I suppose I'm not adding it correctly in the above handler?
private void addressUserControlButton_Click(object sender, EventArgs e)
{
Button thisButton = sender as Button;
thisButton.Text = "Why Hello";
}
EDIT - Ok, so I moved the eventhandler assignment to Page_PreInit instead of within btnAddAddress_Click, like so....
protected void Page_PreInit(object sender, EventArgs e)
{
int addressCount = 0;
foreach (AddressUserControl aCntrl in addresses)
{
Literal ltlSpace = new Literal();
ltlSpace.Text = "<br /><br />";
phAddresses.Controls.Add(aCntrl);
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addressCount;
addressUserControlButton.Click += new EventHandler(addressUserControlButton_Click);
phAddresses.Controls.Add(ltlSpace);
addressCount++;
}
}
Not totally clear on why or how this fixed the problem though.

When you add any control programmatically, you need to register click event after that.

Related

Timer in ASP.NET webform to update a label text

I use this code for create timer that want to update a label each second:
timer = new System.Timers.Timer();
timer.Elapsed += new ElapsedEventHandler(OnRefresh_Tick);
timer.Interval = 1000;
The function OnRefresh_Tick call each second but the label text doesn't change.
Edit:
I use the below code for the timer, but when the timer starts, I can't write in the second textbox (txtPassword) and it refreshes and the cursor goes to the first textbox (txtUserName)
.aspx file:
<form id="form1" runat="server">
<br /><br />
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtUserName" runat="server" Height="30px" Width="100px"></asp:TextBox><br /><br />
<asp:TextBox ID="txtPassword" runat="server" Height="30px" Width="100px"></asp:TextBox><br /><br />
<asp:Label runat="server" id="lnkSendVerificationCode"></asp:Label><br /><br />
<asp:Button ID="Button1" runat="server" Text="Start Timer" CssClass="btn" OnClick="Button1_Click"/>
<asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000" OnTick="Timer1_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</form>
.cs file:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
}
}
protected void Button1_Click(object sender,EventArgs e)
{
Session["VerificationCodeCounter"] = "20";
Timer1.Enabled = true;
}//Button1_Click
protected void Timer1_Tick(object sender, EventArgs e)
{
int sendVerificationCounter = -1;
try { sendVerificationCounter = int.Parse(Session["VerificationCodeCounter"].ToString()); } catch { }//catch
if (sendVerificationCounter == 1)
{
sendVerificationCounter = -1;
Session["VerificationCodeCounter"] = sendVerificationCounter.ToString();
Timer1.Enabled = false;
}//if
else if (sendVerificationCounter > 0)
{
sendVerificationCounter--;
lnkSendVerificationCode.Text = sendVerificationCounter.ToString();
Session["VerificationCodeCounter"] = sendVerificationCounter.ToString();
}//else if
}//Button1_Click
Try say this:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="padding:25px">
<h4>enter seconds to count down</h4>
<asp:TextBox ID="txtCount" runat="server"
Height="42px"
Width="80px"
Font-Size="XX-Large"
Text="0"
style="text-align: center">
</asp:TextBox>
<br />
<asp:Button ID="Button1" runat="server" Text="Start Timer" CssClass="btn" OnClick="Button1_Click"/>
<asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000" OnTick="Timer1_Tick"></asp:Timer>
<br />
</div>
And code behind would be this:
protected void Button1_Click(object sender, EventArgs e)
{
Timer1.Interval = 1000; // tick our timer each second
Timer1.Enabled = true;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int MyCount = Convert.ToInt32(txtCount.Text);
if (MyCount > 0 )
{
MyCount = MyCount - 1;
txtCount.Text = MyCount.ToString();
}
else
{
// we are done, stop the timer
Timer1.Enabled = false;
}
}
So, we now see this if we enter 10 (for 10 seconds).
If we hit start timer, then it counts down to 0, and then stops the timer.
Edit: With a up-date panel
So, if we don't want a whole page re-fresh, then we can use this:
<h4>enter seconds to count down</h4>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtCount" runat="server"
Height="42px"
Width="80px"
Font-Size="XX-Large"
Text="0"
style="text-align: center">
</asp:TextBox>
<br />
<asp:Button ID="Button1" runat="server" Text="Start Timer" CssClass="btn" OnClick="Button1_Click"/>
<asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000" OnTick="Timer1_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
Remember, while the whole page will now not re-fresh, do keep in mind that the page life cycle DOES trigger. So, if you have some code in on-page load to setup controls? Then you need this
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// code here to load up grids, and controls
// code here ONLY runs on first time page load
}
}
So, keep in mind that for any up-date panel (button clicks, timer etc.), then the page load event DOES fire each time.
However, that !IsPostback check? The last 100+ web pages I created that loads or sets up ANYTHING on a page will have the above code stub, and check for !IsPostback.
You can't quite even make a working webforms page unless you follow the above rule. What this means is your page can now handle post-backs, and not re-load controls and run the first time setup of such controls.
So, keep in mind, a update panel DOES post-back, and does trigger the page load event. Better said, a update panel, and click of a button (or timer) inside will post-back, but it what we call a partial page post-back.
Edit3: With a label
So, say we want a label - not a text box. Then do this:
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="padding:25px">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="txtCount" runat="server"
Height="42px"
Width="80px"
Font-Size="XX-Large"
Text="999"
style="text-align: center">
</asp:Label>
<br />
<asp:Button ID="Button1" runat="server" Text="Start Timer" CssClass="btn" OnClick="Button1_Click"/>
<asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000" OnTick="Timer1_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
<br />
</div>
</form>
</body>
And now our code becomes this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// code here to load up grids, and controls
// code here ONLY runs on first time page load
txtCount.Text = "10";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Timer1.Interval = 1000; // tick our timer each second
Timer1.Enabled = true;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
int MyCount = Convert.ToInt32(txtCount.Text);
if (MyCount > 0 )
{
MyCount = MyCount - 1;
txtCount.Text = MyCount.ToString();
}
else
{
// we are done, stop the timer
Timer1.Enabled = false;
}
}
And now we see this:

Why does my gridview's edit\update not work after I add item to it at runtime

On my Page I have a textbox and a submit button which adds an item to my gridview which has edit/update functionality.All this is in an update panel.
I am binding my gridview with data from database using sqlreader. The edit/update option works fine when it bind it first time. but once I add an Item at runtime, the newly added item gets added to my gridview but edit update stops working. Also, not able to add new item after that.
Please find my sample code below
This is my HTML code:
-
<li>
<input type="radio" id="tabb" name="tabs11"/>
<label for="tabb">Family Name</label>
<div id="tab-content12" class="tab-content animated fadeIn" style="background-color:white; padding:10px;" >
<asp:UpdatePanel ID="UpdatePanel4" runat="server">
<ContentTemplate>
<asp:Button ID="BtnAddFamilyName" runat="server" Text="Add" CssClass="buttons" OnClick="BtnAddFamilyName_Click" /><br />
<asp:Label ID="Label1" runat="server" Text="Enter Family Name"></asp:Label>
<asp:TextBox ID="FamilyNameTextBox" runat="server" CssClass="inputs" placeholder="Enter Family Name"></asp:TextBox>
<asp:Button ID="BtnSubmitFamilyName" runat="server" Text="Submit" OnClick="BtnSubmitFamilyName_Click" CssClass="inputs"/><br /><br />
<asp:GridView ID="gdvEDitFamilyName" runat="server" OnRowEditing="gdvEDitFamilyName_RowEditing" OnRowCancelingEdit="gdvEDitFamilyName_RowCancelingEdit" OnRowUpdating="gdvEDitFamilyName_RowUpdating" AutoGenerateEditButton="true" DataKeyNames="FamilyId" CssClass="grid" RowStyle-CssClass="rows">
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</li>
2: My code behind for binding the gridview:
SqlDataReader reader = DataExecuter.ReadMultipleRows("spBindHIGridview",
CommandType.StoredProcedure);
reader.NextResult();
gdvEDitFamilyName.DataSource = reader;
gdvEDitFamilyName.DataBind();
3:My code behind for adding the item to the grid:
protected void BtnSubmitFamilyName_Click(object sender, EventArgs e)
{
if (FamilyNameTextBox.Text.Equals(""))
{
ScriptManager.RegisterClientScriptBlock(this,
this.GetType(), "alertMessage", "alert('Please enter a
value')", true);
}
else
{
DataExecuter.ExecuteCommand("spInsertFamilyName", new[,] { {
"#FamilyName", FamilyNameTextBox.Text } },
CommandType.StoredProcedure);
this.BindDdl();
this.BindGrid();
ScriptManager.RegisterClientScriptBlock(this,
this.GetType(), "alertMessage", "alert('Record Inserted
Successfully')", true);
}
}
After the 3rd step i can't add a new item or edit/update the gridview

Required Field Validator not working on controls inside dynamically generated user control

I have a user control containing few server controls like text boxes and drop down lists.
i have also added few required field validation controls. Normally these validation work fine, if I add the user control in design time.
But when I add the user control dynamically, the validation control just don’t work and page is posted back.
User Control:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="myUserControl.ascx.cs" Inherits="myUserControl" %>
<table cellpadding="0" cellspacing="0" >
<tr>
<td>
<asp:TextBox runat="server" ID="txtLastName" Width="80px" MaxLength="64" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="txtLastName" runat="server" ErrorMessage="Required Value" Display="None"></asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender1" runat="server" TargetControlID="RequiredFieldValidator1"></ajaxToolkit:ValidatorCalloutExtender>
</td>
<td>
<asp:TextBox runat="server" ID="txtFirstName" Width="80px" MaxLength="64" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="txtFirstName" runat="server" ErrorMessage="Required Value" Display="None"></asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender2" runat="server" TargetControlID="RequiredFieldValidator2"></ajaxToolkit:ValidatorCalloutExtender>
</td>
<td>
<asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="DeleteButton_Click" CausesValidation="false" />
</td>
</tr>
</table>
Containing Form Markup:
<form id="form1" runat="server">
<div>
<div align="right" ><asp:Button ID="btnAdd" runat="server" Text="Add Order Line" onclick="btnAdd_Click" CausesValidation="false" /></div>
<asp:PlaceHolder runat="server" ID="DynamicNameList" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" />
</div>
</form>
Containing Form Code:
public partial class WebForm1 : System.Web.UI.Page, IDynamicControlContainer
{
protected void Page_Load(object sender, EventArgs e)
{
foreach (string id in LoadControlIdList())
{
Create(id);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
Create(null);
}
public void Create(string id)
{
string targetId = id ?? Guid.NewGuid().ToString();
myUserControl control = LoadControl("~/CustomControls/myUserControl.ascx") as myUserControl;
control.ID = targetId;
DynamicNameList.Controls.Add(control);
SaveControlIdList();
}
public void Delete(Control control)
{
DynamicNameList.Controls.Remove(control);
SaveControlIdList();
}
public void SaveControlIdList()
{
List<string> idList = new List<string>();
foreach (Control control in DynamicNameList.Controls)
{
idList.Add(control.ID);
}
ViewState["IdList"] = idList;
}
public string[] LoadControlIdList()
{
var list = (List<string>)ViewState["IdList"];
if (list == null)
{
return new string[0];
}
return list.ToArray();
}
}
public interface IDynamicControlContainer
{
/// <summary>
/// Deletes the specified control from the container
/// </summary>
/// <param name="control">The control.</param>
void Delete(Control control);
}
}
You need to use either the Page_Init or CreateChildControls events to do this. By the time Page_Load kicks in, the control tree is already loaded.

get info from one page and show it on other page

i m working on shopping cart site
i want to show complete information of a product contained in a div section. on an other page. i have may div that contained information.
goal is to get the info on a new page when user clicks some product's image.
Error:
Control 'MainContent_ImageButton1' of type 'ImageButton' must be placed inside a form tag with runat=server.
HTML:
<div id="physics" runat="server">
<h3>High School Physics</h3>
<%-- <img src="images/Book.jpg" /> --%>
<asp:ImageButton ID="ImageButton1"
src="images/Book.jpg" runat="server" onclick="ImageButton1_Click" />
<p> Book Description Goes Here
<br />
<asp:Label ID="Label1" runat="server" Text="Label">PKR 770/-</asp:Label>
<br />
<asp:TextBox ID="TextBox1" Text="1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add" />
</p>
</div>
Code :
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
StringWriter sw = new StringWriter();
HtmlTextWriter w = new HtmlTextWriter(sw);
physics.RenderControl(w);
Session["mySessionVar"] = sw.GetStringBuilder().ToString();
Response.Redirect("ShowLarge.aspx", true);
}
HTML: where i want to show this info
<div id="ShowInLargeView" runat="server">
</div>
Code:
protected void Page_Load(object sender, EventArgs e)
{
ShowInLargeView.InnerHtml = (String)Session["mySessionVar"];
}
i want to show the complete info of Div in an other page. i m getting an error. this scenario is about shopping cart
i need help
please help.
The error you are getting is related to the fact that you are trying to add an event handler
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
In order to add an event handler to an element on your page it will need to be encapsulated in a 'form' with the runat="server" attribute. this will result in the click event of the ImageButton ending up in your code-behind.
so your aspx would become something like :
<form runat="server">
<div id="physics" runat="server">
<h3>High School Physics</h3>
<%-- <img src="images/Book.jpg" /> --%>
<asp:ImageButton ID="ImageButton1"
src="images/Book.jpg" runat="server" onclick="ImageButton1_Click" />
<p> Book Description Goes Here
<br />
<asp:Label ID="Label1" runat="server" Text="Label">PKR 770/-</asp:Label>
<br />
<asp:TextBox ID="TextBox1" Text="1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add" />
</p>
</div>
</form>
In general it should suffice to encapsulate your entire page in a form tag, this way all events will be passed to your code-behind.

when i try to check if a radio button is checked, the code doesnt execute

i am trying 2 make a quiz in asp.net.
the mcq choices r displayed using radio buttons. in code behind, when i try 2 check if radiobutton is checked, d code under that if statement does not execute.
aspx code:
<ItemTemplate>
<asp:Literal ID="Literal1" runat="server" Text='<%#Eval("ques") %>'></asp:Literal><br />
<asp:RadioButton GroupName="a" ID="RadioButton1" Text='<%#Eval("ch1") %>' runat="server" /><br />
<asp:RadioButton GroupName="a" ID="RadioButton2" Text='<%#Eval("ch2") %>' runat="server" /><br />
<asp:RadioButton GroupName="a" ID="RadioButton3" Text='<%#Eval("ch3") %>' runat="server" /><br />
<asp:RadioButton GroupName="a" ID="RadioButton4" Text='<%#Eval("ch4") %>' runat="server" /><br />
<asp:Label ID="Label1" runat="server" Text='<%#Eval("ans") %>' Visible="false"></asp:Label><br />
<asp:Label ID="Label3" runat="server" Text="Label"></asp:Label><br />
</ItemTemplate>
code behind:
protected void Button1_Click(object sender, EventArgs e)
{
int count = 0;
foreach(RepeaterItem Items in Repeater1.Items)
{
RadioButton r1 = (RadioButton)Items.FindControl("RadioButton1");
RadioButton r2 = (RadioButton)Items.FindControl("RadioButton2");
RadioButton r3 = (RadioButton)Items.FindControl("RadioButton3");
RadioButton r4 = (RadioButton)Items.FindControl("RadioButton4");
Label l3 = (Label)Items.FindControl("Label3");
Label l=(Label)Items.FindControl("Label1");
l3.Text = "hello?";
if (r1.Checked)
{
if(r1.Text==l.Text)
count++;
}
else
{
if (r2.Checked)
{
if(r2.Text==l.Text)
count++;
}
}
// and so on for all 4 options
}
Label2.Visible = true;
Label2.Text = "your score is " + count; //always zero!
}
If you're stepping through the debugger, and your line
if(r1.Text==l.Text)
count++;
isn't executing, then I would guess that the line if (r1.Checked) is evaluating to false.
On your Page_Load() method for this page, are there any databindings or manipulation of these radio buttons? If so, unless you wrap them in a if(!Page.IsPostBack){ ... } conditional then it will wipe out whatever the user did to the radio button, hence r1.Checked would be false.
I hope that might help :) Good luck.
You'll need to do the following:
Set the AutoPostBack on the radio button control to true.
Set the OnItemCommand on the repeater control to "Button1_Click"
Change the signature of the Button1_Click method to protected void Button1_Click(object sender, RepeaterCommandEventArgs e)
That will at least trigger the method in your code behind.

Resources