Dynamic button click event created OnPreRender doesn't fire - c#

I am creating a button dynamically in the PreRender event like this:
Button myButton = new Button();
myButton.Text = "Test";
myButton.Click += new EventHandler(myButton_Click);
myDiv.Controls.Add(myButton);
This button is render in the browser, but when I click the button, the click event doesn't fire. I tried to create an identical button in the PageLoad event and it works perfectly, but I must create this button it the PreRender event, since creating this dynamic button or not depends on a value which I get only in this event. What can I do so when I click a dynamic button created in the PreRender, the click event fires?

You should add your button to the page in the page's OnInit event and wire up it's click event during or before OnLoad and then you can enable/disable your button or make visible/invisible your button using the variable that you will have during the PreRender event. See Joel Coehoorn's answer to this question for more details. Otherwise try using a PlaceHolder control though that may end up being trickier.
protected override void OnInit (EventArgs e)
{
Button myButton = new Button();
myButton.Text = "Test";
myButton.Click += new EventHandler(myButton_Click);
myDiv.Controls.Add(myButton);
base.OnInit(e);
}
protected override void OnPreRender(EventArgs e)
{
myButton.Visible = myConditional;
base.OnPreRender(e);
}

Maybe create the button in the PreRender and bind the click event in PageLoad?

In PreRender you can create some var, which will tell you, that you need create button.
And on Render create that button by hand with need JavaScript or with sending form. But you can't use such simple syntax as +=EventHandler, more code need.

According to this link from MSDN, you must add button and event related to it if needed durign the OnInit() as explained here : MSDN Lifecycle
"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."
To do so, try something like that :
protected override void OnInit(EventArgs e)
{
// Do some stuff here
base.OnInit(e);
}

You should move control creation earlier in the page lifecycle. Control events are fired after Load and before PreRender so OnLoad or anything earlier should do.

You should add the button on the preinit phase, otherwhise it won't fire
Asp net lifecycle
Use this event for the following (PREINIT):
Create or re-create dynamic controls.

Related

C# - dynamically-loading-a-user-control-on-button-click

I am experiencing the almost same issue specified in this question. Can anybody please post the answer for this? The question is not answered in a clear way.
Issue with dynamically loading a user control on button click
In this aforementioned question, he is loading the control to a placeholder present in the first user control. My scenario is slightly different. My scenario is i have a single aspx page, UserControl1 and UserControl2. At the very beginning, I will load UserControl1 to Page. Then I need to unload userControl1 and load UserControl2 to Page when user clicks a button from UserControl1.
Events must be registered on page load not later. Your control is created during event handling and its event is not registered.
Take a look:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
You need to create a custom event handler for UserControl1 and bubble the event up to the page when the button is clicked.
Create a custom event handler for UserControl1:
public event EventHandler UpdateButtonClick;
public void OnUpdateButtonClick(EventArgs e)
{
if (UpdateButtonClick!= null)
UpdateButtonClick(this, e);
}
Assign the event handler for the UserControl1:
<uc:UserControl1 ID="UserControl1" runat="server"
OnUpdateButtonClick="UserControl1_UpdateButtonClick" ... />
Handle the event in the code-behind:
protected void UserControl1_UpdateButtonClick(object sender, EventArgs e)
{
UserControl1.Visible = false;
UserControl2.Visible = true;
}

How to pass info from control to event at Runtime

I'm creating buttons by code inside a FlowLayoutPanel and I can't create a click event for each one of the created buttons. I need some help cause i'm stuck on this.
You can just subscribe to each button's Click event as you create them.
For example:
Button newButton = new Button();
// Setup button...
newButton.Click += this.ClickHandler;
Then, somewhere else:
private void ClickHandler(object sender, RoutedEventArgs e)
{
// Do something here
}
The other, potentially more elegant, option would be to bind the Button's Command to an ICommand. You could also set it's CommandParameter in order to pass additional, button specific, information.
Here's the solution, Manage controls at Runtime.

asp.net user control event propagation trouble

I have a simple user control that contains some buttons that fire events which I want to be handled by the page using the control. I have my code setup as such:
public event EventHandler Cancel;
public event EventHandler Confirm;
public void Confirm_Click(object sender, EventArgs e)
{
if (Confirm != null)
Confirm(this, e);
}
public void Cancel_Click(object sender, EventArgs e)
{
if (Cancel != null)
Cancel(this, e);
}
but when I try to call these from the page that is using the control's page load event I don't get any of the custom events
ASPX Code
<%# Register TagPrefix="btg" TagName="CustomControl" Src="~/Search/CustomControl.ascx" %>
<btg:CustomControl ID="btgControl" runat="server" ></btg:CustomControl>
could this be because my buttons in the user control are within an update panel?
You shouldn't be seeing methods. You should be seeing events.
In your parent page's load, you need to do this:
myUserControl.Cancel += new EventHandler(myUserControl_Cancel);
You can hit tab,tab to auto-generate the method stub. That will look like:
void myUserControl_Cancel(object sender, EventArgs e) {}
Then, this code will fire after it is called in the method of your user control. In order for that code to fire, you'll have to assign the events to button events on your user control.
edit: myUserControl is the id of your user control. Also, some would argue that event handlers should be in your page's init method.
edit:
Is your user control properly referenced in the page? i.e. Are you registering the user control in web.config or using the reference directive in the page?
Also, did you try cleaning the solution and rebuilding? If your user control is dynamically created/loaded, you'll have to wire up the events in the same scope as the instantiated control. In order to dynamically load the user control, you'll have to have a placeholder in your page and do the following:
UserControl control = Page.LoadControl("~/ControlPath/ControlName.ascx");
((MyUserControlClass)control).Cancel += += new EventHandler(myUserControl_Cancel); // etc...

Raise LostFocus event on a control manually

I have a bunch of controls (textbox and combobox) on a form with toolstripcontainer and toolstripbuttons for save, cancel etc for edits. We are using .Net 3.5 SP1
There is bunch of logic written in control.lostfocus and control.leave events. These events are not being called when clicked on the toolstrip buttons. Is there a way to call these events manually when any of these buttons are pressed.
Thanks.
Kishore
[Edit]
This is how I solved the problem. Thanks Chris Marasti-Georg for the pointer. In the button click event I calling focus on the toolstrip instead of the button as the toolstripbutton does not have a focus event. We can access the toolstrip on which the button is placed using
((ToolStripButton)sender).Owner.Focus()
-Kishore
You could listen to the click events on the buttons, and in the handler call their focus method. That would (hopefully) cause the previously focused control to respond correctly. Add the following handler to each button's click event:
private void ButtonClick(object sender, EventArgs e) {
if(sender != null) {
sender.Focus();
}
}
You can extend those controls and then call the OnLostFocus and OnLeave protected methods of the base class...
I'd suggest moving the login to a method outside the event handler and calling that method...

How do you determine when a button is clicked in the child on the parent - ASP.NET

In my child user control I have a gridview with an OnRowCommand eventhandler that is executed when Edit button is click. I want to set the visibility of an ASP.NET placeholder control in the parent to true when the Edit button is clicked in child control.
What would be the best way to accomplish this task?
Update:
After a little bit more research on the internets, I create a public event Eventhandler in my child control and rasied the event when the OnRowCommand event was fired. In my page_load event of my parent control, i mapped the child user control event to an private event in my parent control.
Child Control source code:
public event EventHandler MyEvent;
protected void MyGridView_OnRowCommand(object sender, GridViewCommandEventsArgs e)
{
if(MyEvent != null)
MyEvent(sender, e);
}
Parent Control source code:
protected void Page_Load(object sender, EventArgs e)
{
MyChildControl.MyEvent += new EventHandler(this.MyLocalEvent);
}
private void MyLocalEvent(object sender, EventArgs e)
{
MyPlaceHolder.Visible = true;
MyUpdatePanel.Update();
}
There are two methods in addition to bubbling the event worth considering:
a. Create a new event in your child user control. Listen to this event in the parent control. Fire this event in the child control.
b. Listen to the gridview event OnRowCommand in the parent control.
Approach a is superior because there is less of the abstraction leaking through. B is quick and dirty, but if this is a one-time-use user control, it will not have a negative impact.
Creating events is fairly easy, many programs include templates for events which mean they only thing you type is the name of the event (e.g. Resharper).
Off the top of my head I would either create a new event within the child user control that would fire off when OnRowCommand fires, or use OnBubbleEvent - I can't remember the exact name but it's something like that.

Categories