Calling page event when ASP.NET user control event is invoked - c#

Suppose there is a user control in a page called Paging.ascx that is embedded in PageWithResults.aspx. This control has the necessary properties to keep track of various details about what page you're on (ie: CurrentPage, TotalRecordsInResults, RecordsPerPage, etc..). It also contains events that fire off when you click on a hyperlink ("next page" or "previous page"). Example below. I need to tell PageWithResults.aspx that one of these LinkButton web controls was clicked. I think I need to assign a delegate in the page, so that when this user control event is called (hyperlink is clicked), it also calls some other method/event in the page class. That way I can quickly check what the new value of CurrentPage is (based on what was called in the event below) and get a new result set for the new page (based on the CurrentPage property). But I'm not sure of the best approach. I'm thinking this will require a delegate, but I'm not sure how to wire it up. If you need more details, please ask.
protected void btnNext_Click(object sender, EventArgs e)
{
this.CurrentPage = this.CurrentPage + 1;
if (OnPageChanged != null) OnPageChanged(this.CurrentPage);
}
I'm thinking I have to put my delegate here somewhere. ??
protected void btnNext_Click(object sender, EventArgs e)
{
this.CurrentPage = this.CurrentPage + 1;
if (OnPageChanged != null) OnPageChanged(this.CurrentPage);
//delegate to call object.method or something
}

Using an event would work fine.
You would create the event within your UserControl like so:
public event EventHandler ButtonClicked;
Then invoke the event when required:
protected void Button1_Click(object sender, EventArgs e)
{
if (ButtonClicked != null)
ButtonClicked(this, new EventArgs());
}
In your page you would need to assign an event handler:
protected void Page_Load(object sender, EventArgs e)
{
UserControl1.ButtonClicked += new EventHandler(UserControl1_ButtonClicked);
}
void UserControl1_ButtonClicked(object sender, EventArgs e)
{
}
As well as using the above approach you can also cast the Page reference in the UserControl and call a public method directly:
MyPage page = (MyPage)Page;
page.AMethod();
Hope this helps.

Related

ASP.NET ImageButton Click event

I have a dynamic ImageButton and I want it to trigger a method when it's clicked. I have the following code, which unfortunatelly it's not working.
ImageButton imb = new ImageButton();
imb.Attributes.Add("runat", "server");
imb.Click += new ImageClickEventHandler(ImageButton1_Click);
imb.ID = "ID";
imb.ImageUrl = "link to image";
Panel1.Controls.Add(imb);
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
//it should go here
}
you must add your ImageButton to a suitable continer.
e.g:
form1.Controls.Add(Imb);
/// form1 must have runat=server
you can find useful tips at here.
Adding dynamic controls to the page is a tricky matter. Unfortunately, you cannot just declare an object of WebControl derived type and expect it to work.
In ASP.NET WebForms, there is a concept called Page Lifecycle. It is a broad matter, but my point is that there is a particular order you must obey to plug-in the dynamic control into the page. A practical example follows.
Start with dynamic control declaration at the class level.
protected ImageButton imb = null;
Then you initialize it durring the page initialization. One possibility is to handle the PreInit event.
protected void Page_PreInit(object sender, EventArgs e)
{
imb = new ImageButton()
{
ID = "ID",
ImageUrl = "link to image"
};
imb.Click += Imb_Click;
Panel1.Controls.Add(imb);
}
private void Imb_Click(object sender, ImageClickEventArgs e)
{
// Do your stuff
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set initial properties as appropriate. E.g.
imb.AlternateText = "...";
}
}
You're good to go.

Assigning event handlers to dynamically generated controls

There is an issue that I've been struggling with it which is I generate a button in page load event and I assign a new handler for it but the event is not executed.
I cannot spot the problem.
If there are better ways to do this assignment please inform me about it.
Here is my C# code:
protected void Page_Load(object sender, EventArgs e)
{
Button edit = new Button();
edit.Text = "edit";
edit.ID = "editbtn";
edit.Click += new EventHandler(this.edit_Click);
info.Controls.Add(edit);
}
protected void edit_Click(object sender, EventArgs e)
{
Response.Redirect("Registration.aspx");
}
And info is an existing asp panel on my page.

linkbuttons behaviour postbacks versus not postback

Can you help me understand why, when the page is first loaded by the example below, the buttons don't work as intended eg Button 2 doesn't call GetItems(int.Parse("2"), 3); but rather calls GetItems(int.Parse("4"), 3); however after the first postback all the buttons work correctly e.g. Buttonx calls GetItems(int.Parse("x"), 3);
Thanks
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GetItems(1, 2); //default values (first time the page is loaded)
}
GenerateButtons(5);
}
private void GenerateButtons(int c)
{
LinkButton[] x = new LinkButton[c];
for(int i=0; i<c;i++)
{
x[i] = new LinkButton();
x[i].Text = (i+1).ToString();
Panel1.Controls.Add(x[i]);
x[i].OnClick += new EventHandler(Button_Click);
}
}
protected void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender; // Which button was clicked;
GetItems(int.Parse(button.Text), 3); //3 is a constant; first argument is index of button extracted from its caption
}
PS. when I refer to button 1 I have button[0] in mind. button2=button[1] and so on. after postback button1 is correctly attached to the event to trigger GetItems(1,3). Before the postback button1 causes GetItems(3,3) to run. Not as intended
Use the Page_Init so it will work on the first load
protected void Page_Init(object sender, EventArgs e)
{
GenerateButtons(5);
}
Source: https://msdn.microsoft.com/en-us/library/ms178472.aspx
Init Raised after all controls have been initialized and any skin
settings have been applied. The Init event of individual controls
occurs before the Init event of the page. Use this event to read or
initialize control properties
.
When you dynamically create controls you do so in Page_PreInit not Page_Load
protected void Page_PreInit(object sender, EventArgs e)
{
GenerateButtons(5);
}
This article explains and will help you
http://www.robertsindall.co.uk/blog/dynamically-adding-web-controls/

Running Page Load multiple times

I have a user control on an aspx page that contains filter fields and return a WhereClause. The user conrol will raise an event called FilterApplied when Search is clicked.
On my main form, I add the control with:
<uc1:Filter runat="server" ID="Filter" />
<br />
In my code behind I have:
protected void Page_Load(object sender, EventArgs e)
{
//Register event when filter is changed.
this.Filter.FilterApplied += new EventHandler(this.FilterApplied);
if (Page.IsPostBack)
{ //Do some things that take long
}
}
protected void FilterApplied(object sender, EventArgs e)
{
//Reload the page to refresh the graphs.
Page_Load(sender, e);
}
Problem is:
When I click Search on my user control, the Form_Load runs twice. Once because it is reloaded and then another time because I call it from FilterApplied. If I don't call it from FilterApplied, then the whereclause is still empty.
How can I ensure the Page_Load only run once when Search is clicked?
Your problem lays in multiple registering for FilterApplied event. Each time you call the Page_Load method, you subscribe to this event again. Here is a really simple example of what you are doing, written in WinForms with one button on the form, just to point out your problem:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int numClicks = 0;
private void Form1_Load(object sender, EventArgs e)
{
button1.Click += button1_Click;
this.Text = numClicks.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
numClicks++;
//try uncommenting and commenting next line of code, and observe the difference:
//button1.Click -= button1_Click;
Form1_Load(sender, e);
}
}

How to add EventHandle _NOT_ at Page_Load

I'm making dynamic table at Page_LoadComplete, I cant do in at Page_Load becouse data can be changed during events process, so at Page_LoadComplete i make some buttons and want add them EventHandler:
protected void Page_LoadComplete(object sender, EventArgs e) {
btn.Click += new EventHandler(b_Click);
}
But it doesnt work, how to add events to button not at Page_Load?
simple, even not dynamic code:
void b_Click(object sender, EventArgs e) {
Label1.Text = "!!!";
}
protected void Page_Load(object sender, EventArgs e) {
Button1.Click += new EventHandler(b_Click);
}
on Page_Load works fine.
protected void Page_LoadComplete(object sender, EventArgs e) {
Button1.Click += new EventHandler(b_Click);
}
on Page_LoadComplete do nothing.
Ok here's the example:
Given this html snippet:
<body>
<form id="form1" runat="server">
<div>
<asp:Button runat="server" Text="Click Me" OnClick="go_" />
</div>
</form>
</body>
public partial class WebForm1 : System.Web.UI.Page
{
public int ControlCount
{
get { return ViewState["Controls"] == null ? 0 : (int)ViewState["Controls"]; }
set { ViewState.Add("Controls", value); }
}
protected void Page_Load(object sender, EventArgs e)
{
for(int i = 0; i < ControlCount; i++)
{
Button b = new Button();
b.Click += btn_Click;
b.Text = "Hi";
form1.Controls.Add(b);
}
}
void btn_Click(object sender, EventArgs e)
{
((Button)sender).Text = "bye";
}
protected void go_(object sender, EventArgs e)
{
Button btn = new Button();
btn.Text = "Hi";
form1.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
ControlCount++;
}
}
Every time you click the first button a new button will be added to the page with the text "Hi", and every time you click a "Hi" button the text for THAT button only will change to "Bye"
This works because I add the controls twice. Once in the event handler of the main button, where I determine that I need a new control, and then AGAIN in OnLoad where I have a new, empty page again, but now I know (via ControlCount) how many controls I added.
The problem is the control doesn't exist on postback (since you created it at run time). Creating the control in Init should solve this, and will allow the event to fire. You can change all of the properties in LoadComplete if you like, but the button needs to exist at that point.
What you're trying will never work because controls that are added dynamically must be REadded every time the page reloads.
Since your control population is based on the data being used in the form, you should put all your control creation logic in a single function, and in your event handlers, maniuplate the data then call your control creation logic function, while in Page Load you would JUST call the control creation function (presuming that you've already persisted the data between calls) so that all the controls that were created the first go around get recreated. Then, once they have been recreated, they can respond to the events that they fired.

Categories