Submit is not working - asp.net

I'm using dynamic controls at my ASP.NET applications. So the issue is - when I use these controls separatelly - they work well. But when I put these two controls on the same page - ONLY LAST submit event is fired. Could anyone help me to identify where is the issue and how to fix it?
Here is my aspx layout:
<%# Control Language="C#" AutoEventWireup="True" CodeBehind="MYPAGE.ascx.cs" Inherits="MYNAMESPACE" %>
<%# Register Assembly="MYANOTHERNAMESPACE" Namespace="MYNAMESPACE" TagPrefix="DAControl" %>
...
<div>
<DAControl:ChooseImageDialog runat="server" id="ChooseImageDialog" />
<DAControl:ChooseVideoDialog runat="server" id="ChooseVideoDialog" />
</div>
Here is my 1st control:
[ToolboxData("<{0}:ChooseImageDialog runat=server></{0}:ChooseImageDialog>")]
public class ChooseImageDialog : WebControl
{
/* This is only part of my code, which should enough for explaining the issue*/
private Button applyPreview = new Button();
private Button cancelPreview = new Button();
protected override void OnLoad(EventArgs e)
{
applyPreview.Click += new EventHandler(applyPreview_Click);
base.OnLoad(e);
}
void applyPreview_Click(object sender, EventArgs e)
{
// I want to reach this block
}
}
}
Here is my 2nd control:
[ToolboxData("<{0}:ChooseVideoDialog runat=server></{0}:ChooseVideoDialog>")]
public class ChooseVideoDialog : WebControl
{
/* This is only part of my code, which should enough for explaining the issue*/
private Button applyVideoPreview = new Button();
private Button cancelPreview = new Button();
protected override void OnLoad(EventArgs e)
{
applyVideoPreview.Click += new EventHandler(ApplyPreviewVideo_Click);
base.OnLoad(e);
}
void ApplyPreviewVideo_Click(object sender, EventArgs e)
{
// I want to reach this block
}
}

Events must be wired up in the Init event. Any later in the life cycle is too late.

Related

Adding User-Control when clicking a button

I created a user-control (customized calendar - but it doesn't matter).
In addition, I have a button control, and my target is to add to the page the calendar (the user-control) when clicking on the button. The number of calendars in the page is unlimited, I do not want to add only one calendar to the page.
protected void addCalendar_Click(object sender, EventArgs e)
{
// clicked on button, should add the user control.
}
The user-control is already registered on the page:
<%# Register src="CalendarUserControl.ascx" tagname="CalendarUserControl" tagprefix="uc" %>
Each calendar should be appended to the following div (this div is defined in the aspx page):
<div id="calendars-holder">
// first calendar appended
// second calendar appended
// and so on..
</div>
protected int countCalendars;
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["countCalendars"] != null)
countCalendars = (int) ViewState["countCalendars"];
// init
if (!IsPostBack)
countCalendars = 0;
// register existing user-controls; won't occur before onclick button
// so ViewState["countCalendar"] will be exist.
for (int i = 0; i < countCalendars; i++)
addCalendar(i);
}
// onclick button
protected void addCalender_Click(object sender, EventArgs e)
{
addCalendar(countCalendars++);
ViewState["countCalendars"] = countCalendars;
}
// Adding a new User-Control
protected void addCalendar(int idNumber)
{
CalculatorUserControl Calendar = LoadControl("~/CalendarUserControl.ascx") as CalendarUserControl;
Calendar.ID = "CalculatorUserControl" + idNumber.ToString();
PlaceHolder1.Controls.Add(Calendar);
}

How to add event to custom control that fired when click a button in it?

I want to build custom control consist of html code which shows table, and in the footer of this table I need to add three buttons.
What I did is inherit from WebControl class:
public class MyCustomControl : WebControl {
protected override void RenderContents(HtmlTextWriter output)
{
// using output.Write I write the table in html code
// and I write the three buttons using <input> tag in html not <asp:button> tag
}
}
What I want here is to add three events one to each button I wrote, and those events would be used in the user interface and fired when the proper button clicked:
<asp:MyCustomControl runat="server" id="myCtrl" onButton1Click="Button1_Click" onButton2Click="Button2_Click" />
How can I do this ?
Thanx
**UPDATE1:
The render code in my custom control would be like this:
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<table> ......");
output.Write("<input id='button1' type='button'>");
output.Write("<input id='button2' type='button'>");
output.Write("<input id='button3' type='button'>");
output.Write(".........</table>");
}
So how would I make 'button1' fire the event on server side?
**UPDATE2:
This is what the code looks like:
public class MyCustomControl : WebControl
{
public Button Button1 = new Button {Text = "Button1"};
public Button Button2 = new Button {Text = "Button2"};
public event EventHandler Button1_Click;
public event EventHandler Button2_Click;
protected override void OnPreRender(EventArgs e)
{
Button1.Click += Button1Click;
Button2.Click += Button2Click;
base.OnPreRender(e);
}
protected override void RenderContents(HtmlTextWriter output)
{
using (var plh = new PlaceHolder())
{
var htmlCode = new StringBuilder();
htmlCode.Append("....html code for table...");
var container = new HtmlGenericControl { InnerHtml = htmlCode.ToString() };
plh.Controls.Add(container);
plh.Controls.Add(Button1);
plh.Controls.Add(Button2);
plh.RenderControl(output);
htmlCode.Append("..../html code for table...");
}
}
private void Button1Click(object sender, EventArgs e)
{
if (Button1_Click != null)
Button1_Click(this, e);
}
private void Button2Click(object sender, EventArgs e)
{
if (Button2_Click != null)
Button2_Click(this, e);
}
And in the page.aspx:
<cc1:MyCustomControl ID="myCtrl" runat="server" onbutton1_click="MyCustomControl_Button1_Click" />
But even with this the button1's click method 'MyCustomControl_Button1_Click' not called.
declare your new events like this:
public event EventHandler OnButton1Click;
public event EventHandler OnButton2Click;
public event EventHandler OnButton3Click;
this in the click method on each button do something like this:
public void Button1_Click(object sender, EventArgs e)
{
if (OnButton1Click != null)
OnButton1Click(this, null);
}
Within MyCustomControl class, define events that take (object sender, EventArgs e) and return void.
Then add (still within MyCustomControl) the event handlers for the click events of the internal buttons.
Inside these methods, do CustomClickEvent.Invoke().
Then, in the page containing your custom control, do myControl.CustomClickEvent += new CustomClickEvent(name_of_method_within_page);
To render an asp control from your Custom Control do that from Render base method:
protected override void Render(HtmlTextWriter writer)
Prepare before your controls with this method
protected override void CreateChildControls()

Event Bubbling From Web User Controls in ASP.NET

I have two UserControls - UserControl1.ascx and UserControl2.ascx in PageDefault.aspx:
How I can call the method (GetLabelText() in UserControl1.ascx) from UserControl2.ascx using event bubbling?
This is my example code - When I click on the button (UserControl2Button1 in UserControl1.ascx) - I want to call the method GetLabelText() from UserControl2.ascx - using event bubbling.
PageDefault.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="PageDefault.aspx.cs" Inherits="TelerikAjaxEvents.PageDefault" %>
<%# Register TagPrefix="uc" TagName="UserControl1" Src="~/UserControl1.ascx" %>
<%# Register TagPrefix="uc" TagName="UserControl2" Src="~/UserControl2.ascx" %>
<!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">
<title>Page Default</title>
</head>
<body>
<form id="form1" runat="server">
UserControl1:
<uc:UserControl1 ID="UserControl1" runat="server" />
UserControl2:
<uc:UserControl2 ID="UserControl2" runat="server" />
</form>
</body>
</html>
UserControl1.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="UserControl1.ascx.cs" Inherits="TelerikAjaxEvents.UserControl1" %>
<asp:Label ID="UserControl1Label1" runat="server"></asp:Label>
UserControl1.ascx.cs
public partial class UserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void GetLabelText()
{
UserControl1Label1.Text = "Text is Visible";
}
}
UserControl2.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="UserControl2.ascx.cs" Inherits="TelerikAjaxEvents.UserControl2" %>
<asp:Button ID="UserControl2Button1" runat="server" Text="Send"
onclick="UserControl2Button1_Click" />
UserControl2.ascx.cs
public partial class UserControl2 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void UserControl2Button1_Click(object sender, EventArgs e)
{
//Call method from UserControl1 (GetLabelText()) - Show Label text - USING BUBBLE EVENT
}
}
There are many ways to go about this. Mark's answer hints at what was classically known as event bubbling using a built in functionality part of System.Web.UI.Control base control. However, it's a simple exercise to expose your own event, bind to it, and bubble up events through a control hierarchy. For more details on using BubbleEvent in ASP.NET read the following. Please keep in mind that both of these MSDN articles were written for .NET 1.1
Bubbling an Event
Event Bubbling Control Sample
K. Scott Allen does a good job at demonstrating exactly what an "event bubbling" implementation looks like in his post: Event Bubbling From Web User Controls in ASP.NET (C#) . See the following modification to your example for inspiration.
UserControl1 with GetLabelText()
public partial class UserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void GetLabelText()
{
UserControl1Label1.Text = "Text is Visible";
}
}
UserControl2 with exposed BubbleClick event handler that callers can subscribe to.
public partial class UserControl2 : System.Web.UI.UserControl
{
protected Button UserControl2Button1;
protected void Page_Load(object sender, EventArgs e)
{
}
public event EventHandler BubbleClick;
protected void OnBubbleClick(EventArgs e)
{
if(BubbleClick != null)
{
BubbleClick(this, e);
}
}
protected void UserControl2Button1_Click(object sender, EventArgs e)
{
// do some stuff
OnBubbleClick(e);
}
}
PageDefault subscribes to UserControl2's BubbleClick event handler and executes UserControl1.GetLabelText()
public partial class PageDefault : WebPage
{
UserControl1 userControl1;
UserControl2 userControl2;
protected void Page_Load(object sender, EventArgs e)
{
UserControl2.BubbleClick += RootBubbleClickHandler;
}
protected void RootBubbleClickHandler(object sender, EventArgs e)
{
if (sender is UserControl2)
{
// subscribe UserControl1 to UserControl2 click event and do something
userControl1.GetLabelText();
}
// check for other controls with "BubbleClicks"
}
}
Event Bubbling is a poorly understood concept in ASP.NET WebForms. It does exist (and is used by most of the databound controls), but is often mistaken for the simpler concept of "implement an event in a user control" (as K Scott Allen does).
The core of event bubbling is that the event travels up through the control hierarchy until it is handled or hits the root. This allows some centralization of handler code. It is implemented using the Control.RaiseBubbleEvent and Control.OnBubbleEvent methods. The main use case is controls with a lot of child controls (think Repeaters, ListViews, etc.). Instead of subscribing to each individual control, the Repeater catches them all in it's OnBubbleEvent and raises a single ItemCommandEvent for them.
If you really wanted to use event bubbling (as opposed to K. Scott's example), it'd look something like:
class Page {
override bool OnBubbleEvent(object sender, EventArgs e) {
var btn = sender as Button;
if (btn == null) return false;
// You may want to do further checking that the source is what you want
// You could use CommandEventArgs to do this
this.uc1.GetLabelText();
return true;
}
}
The sequence of events goes like this:
- Button Clicked
- Button RaiseBubbleEvent
- UserControl OnBubbleEvent returns false (default, since you didn't override)
- Page OnBubbleEvent
Can you try declaring the UserControl1 as public property(e.g. "UserControl1") on the PageDefault.aspx and then in the UserControl2, use Parent.Page.UserControl1.GetLabelText()?

Viewstate null on postback

So I have a listbox on my page and some textfields. Through the textfields I can add an item to my listbox (click the button, it adds it to a private List which is then set as a ViewState and the list is databound again). My listbox is also in an updatepanel which gets triggered on the button's Click event. Problem: My Viewstate remains null on a postback so it gets reset each time.
Some code:
private const string VIEW_INGREDIENTS = "IngredientsList";
private const string VIEW_LANGUAGE = "CurrentLanguage";
private List<IngredientData> _ingredientsList;
protected void Page_PreInit(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (ViewState[VIEW_INGREDIENTS] != null)
{
_ingredientsList = (List<IngredientData>) ViewState[VIEW_INGREDIENTS];
}
}
else
{
// prepare ingredient lists
_ingredientsList = new List<IngredientData>();
}
}
protected void Page_Load(object sender, EventArgs e)
{
lstIngredients.DataSource = _ingredientsList;
lstIngredients.DataTextField = "Text";
lstIngredients.DataValueField = "Name";
lstIngredients.DataBind();
}
protected void btnAddIngredient_Click(object sender, EventArgs e)
{
_ingredientsList.Add(new IngredientData { Name = txtIngredientName.Text, Quantity = txtUnitQuantity.Text, Unit = lstUnits.SelectedValue });
ViewState[VIEW_INGREDIENTS] = _ingredientsList;
lstIngredients.DataSource = _ingredientsList;
lstIngredients.DataBind();
}
You're using vewstate during PreInit ? Try to check that a bit later during PreLoad.
Check if the page has EnableViewState="true":
<%# Page Language="C#" EnableViewState="true" ...
And verify the site-wide setting in web.config:
<pages enableViewState="true" enableViewStateMac="true" ... />
Now ASP.NET has built-in viewstate for list controls, so I wonder why you're writing custom code for it. The default viewstate should work well for what you're trying to accomplish.

Pass MasterPage ImageButton event to content Page

I have ImageButton in a MasterPage. I want the OnClick event to fire and be captured by the .ASPX page hosted inside the MasterPage?
MasterPage:
<asp:ImageButton ID="btnClear" OnClick="Clear_Click"
ImageUrl="images/Back_Icon_06.png" runat="server" AlternateText="Clear"
width="38" height="39"/>
The masterpage is actually a child of the page (in fact, it's a UserControl). We don't want the page to have to be aware of the intimate details of its child controls (thats why we delegate those aspects to those controls in the first place), so the correct approach would be to handle the click event on the master page and from there fire another event on the masterpage which the page handles:
Master:
public event EventHandler SomethingHappened;
protected void Button_Click(object sender, EventArgs e)
{
OnSomethingHappened(EventArgs.Empty);
}
protected void OnSomethingHappened(EventArgs e)
{
if(this.SomethingHappened != null)
{
this.SomethingHappened(this, e);
}
}
Page:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//allows us to change master pages
if(this.Master is MyMaster)
{
((MyMaster)this.Master).SomethingHappened += new EventHandler(HandleSomethingHappened);
}
}
private void HandleSomethingHappened(object sender, EventArgs e)
{
//deal with it
}
I would recommend specifying a strongly typed master page in your content page and exposing the event on the master page side
Here's a good MSDN reference
This is similar to what Rex M specified but just simplifies accessing the Master Page a little bit.
// Master Page Code
public event EventHandler ClearClick
{
add
{
this.btnClear.Click += value;
}
remove
{
this.btnClear.Click -= value;
}
}
// Content Page markup
<%# Page masterPageFile="~/MasterPage.master"%>
<%# MasterType virtualPath="~/MasterPage.master"%>
// Content Page Code
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.Master.ClearClick += new EventHandler(OnClearClick);
}
private void OnClearClick(object sender, EventArgs e)
{
// Handle click here
}

Resources