Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP .NET Button event handlers do not fire on the first click, but on the second click after a PostBack

Background: I am customizing an existing ASP .NET / C# application. It has it's own little "framework" and conventions for developers to follow when extending/customizing its functionality. I am currently extending some of it's administrative functionality, to which the framework provides a contract to enforce implementation of the GetAdministrationInterface() method, which returns System.Web.UI.Control. This method is called during the Page_Load() method of the page hosting the GUI interface.

Problem: I have three buttons in my GUI, each of which have been assigned an Event Handler. My administration GUI loads up perfectly fine, but clicking any of the buttons doesn't do what I expect them to do. However, when I click them a second time, the buttons work.

I placed breakpoints at the beginning of each event handler method and stepped through my code. On the first click, none of the event handlers were triggered. On the second click, they fired.

Any ideas?

Example of Button Definition (within GetAdministrationInterface)

public override Control GetAdministrationInterface() {     // more code...      Button btn = new Button();     btn.Text = "Click Me!";     btn.Click += new EventHandler(Btn_Click);      // more code... } 

Example of Event Handler Method Definition

void Btn_Click(object sender, EventArgs e) {     // Do Something } 

Page_Load Method that calls GetAdministrationInterface

protected void Page_Load(object sender, System.EventArgs e) {     if (!Page.IsAsync)     {         List<AdministrationInterface> interfaces = <DATABASE CALL>;         foreach(AdministrationInteface ai in interfaces)         {             placeholderDiv.Controls.Add(ai.GetAdministrationInterface());         }     } } 
like image 799
John Avatar asked May 04 '10 13:05

John


2 Answers

Good grief! I knew it was going to be something this stupid. Purely my fault of course and my lack of knowledge in ASP .NET.

After doing a multitude of Google searches and eventually being blocked by Google on suspicion of being a bot running automated scripts, I managed to squeeze in one last search in and stumbled across this article. Already at the point of giving up, I tried my best to read the article without skipping 10 lines at a time or looking for pretty pictures. In the section titled Assigning IDs to Dynamically Created Controls, I read these magical and most joyful words:

If you view the source HTML before you click the not-working button and after you have clicked it, you will notice a small difference. The buttons have different HTML IDs before and after the post-back. I got ctl04 and ctl05 before the post-back and ctl02 and ctl03 after the post-back.

ASP.NET button recognizes events by checking for a value for its ID in the Request.Form collection. (In truth it happens differently and controls do not check Request.Form collection by themselves. Page passes post data to controls by their IDs and to controls that are registered to be notified about post data). ASP.NET does not fire the Click event, because the button's ID has changed between the post-backs. The button you have clicked and the button you see after are different buttons for ASP.NET.

Sure enough, when I viewed the HTML the first time, my button had the ID ctl04$ctl36. After clicking the button, my button had the ID ctl04$ctl33.

So there you have it! All I had to do was set the ID on the buttons and presto! My event handlers are now being called!

Sample Solution:

public override Control GetAdministrationInterface() {     // more code...      Button btn = new Button();     btn.Text = "Click Me!";     // !!THE BANE OF MY EXISTENCE!!     btn.ID = "The_Bane_of_My_Existence";     // !!THE BANE OF MY EXISTENCE!!     btn.Click += new EventHandler(Btn_Click);      // more code... } 

What a great way to spend two days...

like image 151
John Avatar answered Sep 23 '22 07:09

John


I had the same problem, but the accepted answer here was not causing it. I had a text box and a search button, and clicking the button the first time didn't perform the search. The event handler of the button wasn't being hit. But clicking the button a second time did trigger the event on the server. Here is why:

If you have an <asp:Textbox> with its AutoPostBack set to true, after typing in the text box and then moving to click a button, the text box causes a post-back immediately the moment it loses focus. So the click even of the button doesn't count (the page is already posted-back as a result of the text box's event). That's why when you click the button a second time, it works because the text box is not involved in the second post-back.

Set the AutoPostBackproperty of the <asp:Textbox> to false to fix this issue.

like image 42
TheAgent Avatar answered Sep 24 '22 07:09

TheAgent