OnClick not firing in UserControl when button is clicked - c#

I have a master page. In the master page I have a UserControl for the footer. In the footer I have a button that is not firing OnClick. During debugging I see the function being called by OnClick, btnSignup_Click, is not getting hit. I can't seem to figure out where the mistake in my code is.
Also I wanted to note that the validation functionality is working correctly.
master.master
<%# Master Language="C#" AutoEventWireup="true" Inherits="master" Codebehind="master.master.cs" %>
<%# Register TagPrefix="xyz" TagName="Footer" Src="~/controls/footer.ascx" %>
<xyz:Footer ID="Footer" runat="server" />
footer.ascx
<%# Control Language="C#" AutoEventWireup="true" Inherits="footer" Codebehind="footer.ascx.cs" %>
<div>
<asp:TextBox ID="fName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorfName" ValidationGroup="validationSignup" Display="Static" ControlToValidate="fName" ErrorMessage="First Name required" runat="server"></asp:RequiredFieldValidator>
</div>
<div class="button">
<asp:Button ID="btnSignup" CommandName="Button" runat="server" ValidationGroup="validationSignup" Text="Signup" HeaderText="Please fill in all required fields before continuing." OnClick="btnSignup_Click"/>
</div>
<div class="validationSummary">
<asp:ValidationSummary ID="ValidationSummary" ValidationGroup="validationSignup" runat="server"></asp:ValidationSummary>
</div>
footer.ascx.cs
public partial class templates_site_footer : BaseUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
btnSignup.Click += new EventHandler(btnSignup_Click);
}
protected void btnSignup_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
return;
// code to execute after button is clicked
}
}

Remove btnSignup.Click += new EventHandler(btnSignup_Click); code from Page_Load event, You had already assigned OnClick event to button in .ASCX markup and no need to check validate of your page again in btnSignup_Click, you can directly write button click event code which you want to execute.
Your Footer User Control Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
//btnSignup.Click += new EventHandler(btnSignup_Click);
}
protected void btnSignup_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
// code to execute after button is clicked
}
else
{
// Your page does not validated.
}
}

Related

Text property of a TextBox is empty when an async PostBack occurs

I've had a look at lots of posts and I feel like I'm going crazy as nothing I've tried seems to work. I simply want to click a button and retrieve the value of a textbox.
I'm using web forms with a site.master so not sure if this could be affecting the problem, but most of the solutions I've seen don't appear to be using a site.master.
I'm not binding the textbox, initially I just wanted to create a contact form.
<%# Page Title="About" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="Blackburn_Pulse.About" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<script>$("#menuAbout").addClass("navi-active");</script>
<div class="contentBody">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="tb_Test" EnableViewState="true" CausesValidation="false" runat="server"></asp:TextBox>
<asp:LinkButton ID="btn_Test" runat="server" OnClick="btn_Test_Click" Text="send test" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_Test" EventName="click" />
</Triggers>
</asp:UpdatePanel>
</div>
</asp:Content>
public partial class About : Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.Page.Master.EnableViewState = true;
if (IsPostBack)
{
var test_var = tb_Test.Text; //returning empty
}
}
protected void btn_Test_Click(object sender, EventArgs e)
{
var test_var = tb_Test.Text; //returning empty
}
}
UPDATE:
site.master.cs
public partial class SiteMaster : MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindCategories();
}
}
protected void BindCategories()
{
Categories Categories = new Categories();
rpt_categories.DataSource = Categories.Get_Categories();
rpt_categories.DataBind();
}
protected void lb_newsCat_Command1(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case "naviTo":
//Redirect user to selected category
Response.Redirect("~/" + e.CommandArgument.ToString());
break;
}
}
}
I'm converting a PHP website to an ASP.net website. Turns out I had another HTML form tag on a search box that I haven't started working on yet.
Unfortunately the debugger doesn't throw an error if you have another form tag so anybody else who's just spent hours of their lives searching, double check you don't have more than 1 form tag!
In my site.master.aspx file, I had a search box as follows:
<form method="post" action="?">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-primary my-2 my-sm-0" type="submit">Search</button>
</form>
Once I took the extra form tag out, everything worked fine.

persist ddl values and selected value in between postbacks

I have a save button and a drop down list on a page. Inside the page Load, the drop down list is populated if !Page.PostBack (AutoPostBack=false). So, the first time I load the page, the drop down list is populated. I also have a save method to go with the save button. When this button is clicked, it should do something with the selected value of the drop down list. My problem is that the drop down list has no value (is null) inside the button save method. How would you fix this?
Markup:
MyClass.aspx
<%# Page Language="C#" AutoEventWireup="true" Inherits="MyClass" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainRegion" runat="server">
<div>
<asp:DropDownList ID="myDdl" runat="server" OnSelectedIndexChanged="myDdlChange" ViewStateMode="Enabled" EnableViewState="true" />
</div>
<br />
<div style="min-width: 300px; max-width: 770px;">
<asp:TextBox id="txtBox" runat="server" TextMode="MultiLine" />
</div>
<div class="buttonContainer">
<span >
<asp:Button ID="btnSave" runat="server" Text="Save" onclick="btnSave_Click" />
</span>
</div>
</asp:Content>
Then, in the code behind:
MyClass.aspx.cs
public class MyClass
{
protected global::System.Web.UI.WebControls.DropDownList myDdl;
protected global::System.Web.UI.WebControls.TextBox txtBox;
protected global::System.Web.UI.WebControls.Button btnSave;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.Page.IsPostBack)
Session["selectedID"] = myDdl.SelectedValue; // my attempt to put the selected value from ddl in a session var, to use it later inside the save method but it didn't work
if (!Page.IsPostBack)
{
//create array1 here
myDdl.Items.Clear();
myDdl.Items.AddRange(array1);
Session["selectedID"] = myDdl.SelectedValue;
myDdlChange(null, null);
this.DataBind();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
//do something based on myDdl.SelectedValue (which shouldn't be null)
}
protected void myDdlChange(object source, EventArgs e)
{
txtBox.Text = myDdl.SelectedValue;
}
}
}
I think the main problem is you should be using Page_Load instead of OnLoad.
You don't need to use Session to remember the SelectedValue.
Try something like this which works for me...
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
PopulateDropdown();
}
private void PopulateDropdown()
{
myDdl.Items.Clear();
var array1 = new ListItem[3];
array1[0] = new ListItem("item1", "item1");
array1[1] = new ListItem("item2", "item2");
array1[2] = new ListItem("item3", "item3");
myDdl.Items.AddRange(array1);
myDdl.DataBind();
}
protected void btnSave_Click(object sender, EventArgs e)
{
var selectedVal = myDdl.SelectedValue; // putting a breakpoint here shows myDdl.SelectedValue is not null
}
protected void myDdlChange(object sender, EventArgs e)
{
}

Values in dynamically added controls not retained on postback

I have a page with a number of controls of type MyControl added dynamically. The count is stored in the ViewState, and only incremented with a button click.
In MyControl, I have a TextBox control, and a Label control. When the text is changed in the textbox, the value is multiplied by 2 and displayed in the label control.
To do this, I have added an OnTextChanged event and set AutoPostBack to true.
My problem is this: when I have any number of MyControl's on the page, and change the text in any of the textboxes, the label is updated and the values are retained on postback.
However, if I click the increment button on the page, all the values in the textboxes and labels are lost.
My code:
Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.Default" EnableViewState="true" %>
<html>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
Count:
<asp:Label ID="lblCount" runat="server"></asp:Label>
<asp:Button ID="btnAdd" runat="server" OnClick="btnAdd_Click" Text="+" />
<asp:Panel ID="pnlControls" runat="server"></asp:Panel>
</form>
</body>
</html>
Default.aspx.cs
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int count = 0;
//if not postback, then set count and store in viewstate
if (!Page.IsPostBack)
{
count = 1;
ViewState["count"] = count;
}
LoadControls();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
//increment count
ViewState["count"] = (int)ViewState["count"] + 1;
pnlControls.Controls.Clear();
LoadControls();
}
private void LoadControls()
{
//add controls to page
for (int i = 0; i < (int)ViewState["count"]; i++)
{
MyControl con = (MyControl)LoadControl("MyControl.ascx");
con.ID = i.ToString();
pnlControls.Controls.Add(con);
}
//set count label
lblCount.Text = ViewState["count"].ToString();
}
}
MyControl.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="Test.MyControl" EnableViewState="true" %>
<div>
<asp:TextBox ID="txtField" runat="server" OnTextChanged="txtField_TextChanged" AutoPostBack="true"></asp:TextBox>
<asp:Label ID="lblAnswer" runat="server" Text="answer:"></asp:Label>
</div>
MyControl.ascx.cs
public partial class MyControl : System.Web.UI.UserControl
{
public string Text;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void txtField_TextChanged(object sender, EventArgs e)
{
lblAnswer.Text = (int.Parse(txtField.Text) * 2).ToString();
}
}
Am I missing something obvious? How can I keep the values when the button is clicked?
The reason you lose the info of MyControl(s..) is when you click the button you clear them:
pnlControls.Controls.Clear();
If you want to keep the values I recomended you to use Session variables, for example an array when you fire "txtField_TextChanged" to save "lblAnswer.Text", be carefull with the ID's to differentiate from each other in the Session variable.
Finally, I'd put "LoadControls();" inside Page_Load, outside I think It's redundant.

How To Pass Textbox Value Present In UserControl To Aspx Page Label By Clicking Button In UserControl

TestUC.ascx Design Code
<asp:TextBox ID="txtbox1" runat="server" ClientIDMode="Static" placeholder="Enter Some Text" ></asp:TextBox><br />
<asp:Button ID="btn1" runat="server" Text="Click" OnClick="btn1_Click" ClientIDMode="Static" />
Test.aspx Page Code
<%# Register Src="~/WebUserControls/TestUC.ascx" TagName="WebUserControlTest"
TagPrefix="uctest" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphBody" runat="server">
<asp:Label ID="lbl1" runat="server" >Label</asp:Label>
<uctest:WebUserControlTest ID="ucTest" runat="server"></uctest:WebUserControlTest>
</asp:Content>
OutPut:
I Need ..
Step1: Enter Some text In Text Box
Step2:Then I Click Click Button
[Note: This Two Controls Are Bind From UserControl]
Step3:What Text Entered in TextBox Is Show In label [Note Label Present In Aspx Page]
You will need to have a custom event & you will also need to expose the Text property of the TextBox in your UserControl, like this.
public partial class YourUserControl : UserControl
{
public String Text
{
get
{
return this.txtBox1.Text;
}
//write the setter property if you would like to set the text
//of the TextBox from your aspx page
//set
//{
// this.txtBox1.Text = value;
//}
}
public delegate void TextAppliedEventHandler(Object sender, EventArgs e);
public event TextAppliedEventHandler TextApplied;
protected virtual void OnTextApplied(EventArgs e)
{
//Taking a local copy of the event,
//as events can be subscribed/unsubscribed asynchronously.
//If that happens after the below null check then
//NullReferenceException will be thrown
TextAppliedEventHandler handler = TextApplied;
//Checking if the event has been subscribed or not...
if (handler != null)
handler(this, e);
}
protected void yourUserControlButton_Click(Object sender, EventArgs e)
{
OnTextApplied(EventArgs.Empty);
}
}
Then in your aspx page, where you have placed YourUserControl (OR you are dynamically adding it from the code behind), you can subscribe to this event like this.
protected void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
yourUserControl.TextApplied += new YourUserControl.TextAppliedEventHandler(yourUserControl_TextApplied)
}
}
You can use the custom event of the user control in your page like this.
protected void yourUserControl_TextApplied(Object sender, EventArgs e)
{
yourLabelInYourPage.Text = yourUserControl.Text;
}
And you are done...
EDIT : You can rename the Controls & Events as you like. I have used the names only for the example purpose.
EDIT : In website projects, if you want to add your user control dynamically then,
you might need to include the namespace ASP in your page, like this.
using ASP;
And add this Directive in your page in the aspx markup.
<%# Reference Control="~/PathToYourUserControl/YourUserControl.ascx" %>
other solution : create an event in the usercontrol, which is called in the button click.
Subscribe to this event in the codebehind of the aspx page. that way you can update your interface only if a value is provided.
a little more complicated, but you could re-use this logic to more complex control / parent control feature in the future.
i can add code snippet if asked
This Answer Is Prepared By Help Of #Devraj Gadhavi i Edited Some Code .
UserControl Page Design Code
<asp:TextBox ID="txtbox1" runat="server" ClientIDMode="Static" placeholder="Enter Some Text" ></asp:TextBox><br />
<asp:Button ID="btn1" runat="server" Text="Click" OnClick="btn1_Click" ClientIDMode="Static" />
UserControl Page Code
public partial class TestUC : System.Web.UI.UserControl
{
public String Text
{
get
{
return this.txtbox1.Text;
}
}
public delegate void TextAppliedEventHandler(Object sender, EventArgs e);
public event EventHandler TextApplied;
protected virtual void OnTextApplied(EventArgs e)
{
if (TextApplied != null)
TextApplied(this, e);
}
protected void btn1_Click(object sender, EventArgs e)
{
OnTextApplied(EventArgs.Empty);
}
}
Aspx Page Design Code
<%# Register Src="~/WebUserControls/TestUC.ascx" TagName="WebUserControlTest"
TagPrefix="uctest" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphBody" runat="server">
<asp:Label ID="lbl1" runat="server" >Label</asp:Label>
<uctest:WebUserControlTest ID="ucTest" runat="server"></uctest:WebUserControlTest>
</asp:Content>
Aspx Cs File Code
public partial class Test2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ucTest.TextApplied += new EventHandler(ucTest_TextApplied);
}
protected void ucTest_TextApplied(Object sender, EventArgs e)
{
lbl1.Text = ucTest.Text;
}
}
Another method ,If you don't want to expose the Text property of the TextBox in your UserControl Just use method "UserControl.FindControl("Id Of your Textbox which is present in user control")" in your Case WebUserControlTest.FindControl("txtbox1").
And below is the simpler way to register an event handler on the parent web form's code behind.
Code goes as below for parent form asxp.cs
protected override void OnInit(EventArgs e)
{
//find the button control within the user control
Button button = (Button)WebUserControlTest.FindControl("btn1");
//wire up event handler
button.Click += new EventHandler(button_Click);
base.OnInit(e);
}
void button_Click(object sender, EventArgs e)
{
TextBox txt = (TextBox) WebUserControlTest.FindControl("txtbox1");
//id of lable which is present in the parent webform
lblParentForm.Text=txt.text;
}
Also, you can achieve this using JavaScript like below (given your code above):
<script type="text/javascript">
function getUCTextboxValue() {
let txtName = document.getElementById('<%=ucTest.FindControl("txtbox1").ClientID %>');
let lbl = document.getElementById('<%=lbl1.ClientID %>');
lbl.innerText = txtName.value
}
Also, from the parent page, you can add a HiddenField and save the textbox value on it (using the JavaScript code above) then catch its value from code behind.

ASP.NET Button event is not raised in Web User Control

I have a ASP.NET user control, which contains a Telerik Report Viewer plus a button (server control).
I need to handle some stuff inside the click event of the button, but the event does not seem to fire.
Does anyone know why this is the case?
Here is the HTML directives inside the UserControl:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ReportControl.ascx.cs" Inherits="TelerikReportCustomRetrive.UserControl.ReportControl" %>
Here is the markup inside the UserControl:
<form runat="server" id="form1">
<telerik:ReportViewer ID="ReportViewer1" runat="server" Height="461px" ShowDocumentMapButton="False" ShowHistoryButtons="False" ShowNavigationGroup="False" ShowParametersButton="False" ShowPrintPreviewButton="False"></telerik:ReportViewer>
<asp:Button runat="server" ID="btnNav" OnClick="btnNav_Click" />
And the code behind code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var instanceReportSource = new InstanceReportSource
{
ReportDocument =
new TheReport()
};
ReportViewer1.ReportSource = instanceReportSource;
}
}
protected void btnNav_Click(object sender, EventArgs e)
{
Response.Write("Button Fired!");
}
Delete the if(!PostBack) statement. You should always initialize the control, not only if page is not post back.

Categories