October 28, 2003
<Update date=10 April 2005>This entry gets hit a lot, so I feel obliged to point to some other resources that address this problem. Here are some links:
- First, see all the comments.
- Colt Kwong tried this and it didn't work for him. He suggests another approach.
- Someone reported that Raj Kaimal's solution works for them.
<Update date=4 May 2006> Another update -- Matthew Saunders leaves this comment:
If you're playing in the wonderful land of Asp.Net 2.0 then consider using the form or panel DefaultButton property.I'll also note that the docs say it all. :-)
The link says it all.
A day for blogging ASP.NET stuff, I guess. As a lot of people know and/or have experienced, an ASP.NET page with a single textbox on it doesn't work the way you'd want. (An example would be this very blog, which has a single text box -- the Search box.) Ideally, you type something in and hit Enter; the page should then be submitted and a Click handler invoked.
There seems to be a bug in Internet Explorer. If there's only one textbox on the page, IE submits the page all right, but it neglects to send along information about the button, so no Click handler is invoked. If there is more than one textbox, IE submits the form and "clicks" the first button on the page.
The issue came up yet again today on the aspalliance listserv. Andy and one or two other people pointed the poster to the DefaultButtons control. However, another poster, a guy by the name of Donald Cote, suggested that an easy fix would be to simply add this to the Page_Load handler:
Page.RegisterHiddenField("__EVENTTARGET", ButtonName)where ButtonName is the name of the button whose Click event you want to fire.
This technique leverages the way ASP.NET works with controls such as the LinkButton and Calendar control, or with AutoPostBack controls. Those controls cause the page to be posted when clicked, even though they are not buttons. For this to happen, ASP.NET does three things. First, it adds a hidden field to the page named _EVENTTARGET. ASP.NET also adds some client script to the page (the __doPostBack function) that performs a submit of the form. Finally, it injects client script into each control (or in the case of Calendar, into each cell of the table it generates) that invokes that __doPostBack function when the control is clicked (or whatever), passing to it the name of the control in question. Thus this is what's rendered for an auto-postback CheckBox control:
<input id="CheckBox1" type="checkbox" name="CheckBox1"The __doPostBack function takes the value passed to it and makes it the value of the __EVENTTARGET hidden field and then submits the page. The upshot is that when page is submitted, ASP.NET gets a hidden field named __EVENTTARGET; if that hidden field has a value, ASP.NET can figure out what control caused the form to be submitted.
Pant-pant. This sure got longer than I'd intended. The technique that Donald Cote suggested preempts the hidden field that ASP.NET normally adds to the page and essentially hard-codes the hidden field to always submit the name of your chosen control. This works out quite neatly. If the page is submitted without any click event, ASP.NET accepts the name of your control as the sender. If you click a button on the page, ASP.NET ignores the hidden field in favor of the actual button click. If you have other controls on the page that invoke __doPostBack, then __doPostBack sets the value of the hidden field, overwriting your default value.
You can see this in action by creating a page that has some buttons, a LinkButton, a Calendar, and the aforementioned auto-postback CheckBox control. Then add this code to the page, which displays the information that ASP.NET gets when the page is submitted:
Sub Page_Load()P.S. I've added this little hack to the blog so that the Search button does now work the way I want it to.
Dim i As Integer
For i = 0 To Request.Form.Count - 1
Response.Write("Form: " & Request.Form.Keys(i) & ", value: " _
& Request.Form(i) & "<br>")
Sub Button_Click(sender as Object, e as EventArgs)
Dim b As Button = CType(sender, Button)
Label1.Text = "You clicked " & b.ID