Dynamic Event Handler lost after postback - asp.net

I have a asp.net page with a button, the event the button needs to perform on it's click event needs to vary, dependant on what options are selected further up the page. The button itself is included in the master page, and it's actions are affected by selections made in the child page.
To do this, I have a method in the master page, that is called by the child page, when a users presses a button, that passes the Eventhandler to be used by that button, that is then assigned to masterpage eventhandler for that button:
public void assignEvent( EventHandler saveEvent)
{
this.SaveButtonEvent+= saveEvent
}
Then, when the save button on the master page, it calls that eventhandler
protected void save_Click(object sender, EventArgs e)
{
if (this.SaveButtonEvent != null)
{
this.SaveButtonEvent(this, e);
}
}
The event handler is assigned ok in the first section of code, however because pressing the save button causes a postback, the SaveButtonEvent event handler is set back to being null, and so nothing happens.
How can I preserve the contents of SaveButtonEvent Event Handler during postback, or is there a better way to be doing this?
EDIT:
I can get this to work by saving the EventHandler to the session, but this doesn't seem like a great idea.

When the user presses the button in the child page, store a value (in the viewstate) indicating what event handler should be passed. Then, in the load event of the child page, if it is a postback, always check the stored value and assign the event handler accordingly by calling the master page method.

Related

focus on a user control inside an aspx page after clicking a button inside the user control

I have a user control inside an aspx page, after the aspx page loads, when I click some button inside that user control, I want the focus to come back to user control after that button click action is complete and the aspx page loads again.
You need to have an event in your user control that will allow the .aspx page to subscribe to that event so that it can set focus to the element in the user control after the form posts back, like this:
public class UserControlClass
{
// Define event that will be raised by user control to anyone interested in handling the event
public event UC_Button1ClickEventHandler UC_Button1Click;
public delegate void UC_Button1ClickEventHandler();
// Mechanism to allow event to be raised by user control
private void Button1_Click(System.Object sender, System.EventArgs e)
{
if (UC_Button1Click != null)
{
UC_Button1Click();
}
}
}
Now in your .aspx page, you need to subscribe to the event in the user control and say what method will actually handle the event, like this:
userControl1.UC_Button1Click += Button1_Click;
Finally, the click event handler needs to exist, like this:
public void Button1_Click(object sender, EventArgs args)
{
// Set focus here to user control element, text box for example
((TextBox)userControl.FindControl("TextBox1")).Focus();
}

In WebForms, why does my anonymous event handler not get called when added after OnLoad?

I have an ASP.NET WebForms page with several buttons added programmatically like this:
private void AddExportButton(Control control, Action clickAction) {
LinkButton exportButton = new LinkButton {
Text = "Export",
EnableViewState = false /*Buttons will be recreated on each Postback anyway.*/
};
exportButton.Click += (sender, e) => clickAction();
control.Controls.Add(exportButton);
}
Now this works, as long as the AddExportButton() method is called along the path from the OnLoad() or OnPreLoad() method. It does not fire the handler action however, when AddExportButton() called from the OnLoadComplete() method.
I would like to add/create the buttons also when another event handler (coming from a dropdown) gets called. This only happens after the OnLoad(), which will break my code.
Why is this, and how can I use anonymous methods as event handlers in this case?
See this nice cheat sheet about the ASP.NET Page LifeCycle by Léon Andrianarivony for more info about the order of the page/control creation.
In the page life cycle, the internal RaisePostBackEvent method (which raises the button's Click event) occurs between OnLoad and OnLoadComplete. If you wait until OnLoadComplete to add the LinkButton and hook up its Click event, then obviously the event won't be raised: it's too late.
(The fact that you're using an anonymous method is irrelevant.)
Can you add the export button in the .aspx but set its Visible property to false when you don't want it to appear?

asp.net: How to get a button to affect the page contents

In Page_Load I populate an asp:Table with a grid of images. I have a button that when pressed I would like it to repopulate the page with different images.
However it appears that when the button is pressed Page_Load is called again, followed by the script specified by the button. I thought that I could simply set a variable in the button script which is checked during Page_Load, but this will not work.
What is the most asp.netish way to approach this? Should I be populating my table somewhere other than in Page_Load, or should my button be doing something different?
Your button event gets called after page load. As such, you should put your button code in there.
I'm not terribly sure why you'd try to stuff all of your event code into Page_Load, but it's best to keep it separated.
GOOD
protected void Page_Load(object sender, EventArgs e)
{
MethodThatDynamicallyCreatesControls();
}
protected void MyImage_Click(object sender, EventArgs e)
{
MyImage.Property = newValue;
MyImage2.Property = newValue2;
PopulateTables(newValues);
}
BAD
protected void PageLoad(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
//Check to see if "MyButton" is in the Request
// if it is, it's the button that was clicked
if (Request["MyButton"])
{
MyImage.Property = newValue;
MyImage2.Property = newValue;
PopulateTables(newValues);
}
}
}
As rick said, it's all a matter of understanding the postback.
page_load gets fired every time the page is refreshed. however in many cases, you only want certain things to happen on the first time a page is loaded. in your case, you want the default images to load. by putting all 'one time' events for a page load in a
if (!Page.IsPostback )
{
}
it will only fire on the first time the page is loaded. this is what you want to load your first set of images.
Then in your button click event (which triggers a postback), the code within the if statement will not execute again. and you can load your second set of images in your button's event handler.
That button you're using should call a method in your code behind,so you can know that the button is was clicked, ex:
protected void Important_ButtonClicked(Object sender, EventArgs e)
{
//do what I want to do
}
<asp:Button id="Button1"
Text="MakeChanges"
OnClick="Important_ButtonClicked"
runat="server"/>
Actually I understand what your problem is now, seems like you just have values being set in your page load with no condition check in you page load, so every time you have a postback it refreshes the page to original state, the reason for that is because everytime you trigger a refresh(postback) on the page, the pageload method is invoked, so you need to set original setting in your page load,but have them in the condition, as
if(!Page.Postback) which gets triggered the first time you visit this page. Which means this is where your defaults go and if(Page.Postback) is where your always true things should go. ex:
protected void Page_Load()
{
// this is where I want things to always happen whenever the page is loaded
//for example, no matter what happens I want a certain image in the background
if(!Page.Postback)
{
//set my values for the first and only time
}
else //hint Page.Postback
{
//you can play with the page here to make necessary changes
//but Button click method will still be invoke so thats where button click
//changes should be made
}
}
A PostBack happend when the page is reload. The first page load, Page.IsPostBack has value false. When an event happend, Page.IsPostBack has value true.
So doing the thing like this will definitely works
void Page_Load()
{
if (!Page.IsPostBack)
{
//do your first time binding data
}
How to: Create Event Handlers in ASP.NET Web Pages
EDIT:
Your state change events are not going to fire correctly if you re-bind controls(ie:DropDownList) data on every postback.
void Page_Load()
{
if (!IsPostBack)
{
//load your data
}
}

Row Editing in the grid doesn't work in first click

I have a user control which contains a grid and three buttons for add,edit and delete.
I have placed this user control on an asp.net page.
I have OnClick events for these buttons.
When i click on add and delete buttons it's working fine but when i click on edit button,the onclick event of edit button is fired but the row in the grid doesn't appear in the edit mode, i have to click two times.
I don't know where is the problem.The onclick event handler for edit button is as follows:
protected void btnEditBankAccount_Click(object sender, EventArgs e)
{
grdBankAccounts.EditIndex = grdBankAccounts.SelectedIndex;
grdBankAccounts.RowSelectingEnabled = false;
}
Anyone please help.
my user control has a method which binds the grid to the data source, it's as follows
public void SetSupplierData(SupplierType Supplier)
{
if (Supplier != null)
{
ViewState["SupplierID"] = Supplier.SupplierId;
grdBankAccounts.DataSource = Supplier.BankAccounts;
grdBankAccounts.DataBind();
Session["BankAccounts"] = Supplier.BankAccounts;
}
}
the SetSupplierData method is called from the page where i have my user control.
In order to get this "in-place editing" in grids to work, I typically have to data-bind twice:
once in the OnInit or OnLoad method so that the button click event handlers have the data available to work on
in the OnPreRender method again to show the new values / new state (editing or not)
Marc

Modal popup on dropdown list selection

Is it possible to popup a modal(AJAX) on drop downlist selection.
I have a user control which has a ddl and another usercontrol which has that modal popup.On selection of specific item i need to popup modal.
Modal popup is in another usercontrol.
I did an example of how to do it entirely client side using a ClientEventPool - http://www.aaron-powell.com/blog/january-2009/fun-with-a-client-event-pool-and-modal-popups.aspx
For AJAX work avoid postbacks at all costs!
If I am reading you correctly, you will need to use either chained events or event bubbling to force the drop down selection to fire an event. Then your second user control must listen for that event, and fire the event that "shows" the modal popup.
Without testing code, your structure on the primary control might look like this:
public delegate void DDLHandler(int selectedValue);
public event DDLHandler DDLChanged;
public void DDLChanged(int selection)
{
if (DDLChanged != null)
{
DDLChanged(selection);
}
}
Then you drop down control has it's event wired to call the handler
protected void ddlOne_SelectedIndexChanged(object sender, EventArgs e)
{
//fire event handler for fetching value for this selection
DDLChanged(Int32.Parse(ddlMeasurementOptions.SelectedValue));
}

Resources