Tuesday, April 13, 2010

ASP.Net track focus during postback

Coincidence made it that this week people have asked me twice about how to preserve focus during postbacks, especially during auto postbacks. I didn't really know much about how ASP.Net does this other than building your own script, so I started investigating.

When you post back, there is a postback event reference that is used. The Page.ClientScript property, of the type ClientScriptManager, has a bunch of methods called GetPostBackEventReference which return different script strings for different options. The options are encapsulated into a PostBackOptions object which has, interestingly enough, a property called TrackFocus. Wow! Exactly what I wanted.

The problem comes when digging in the System.Web sources and seeing that no one actually sets this property. I did a bunch of code to add the script with the TrackFocus property and it seems it works. Not only does it preserve the focus before the postback, but also the scroll bars position. I tested in Internet Explorer, FireFox and Chrome and it worked on all.

So what is going on? Why does this feature, which I imagine is quite useful, seem only half done? And that since the era of .Net 2.0? I have no idea. I will post this method, applicable on TextBox controls, although I guess it could be applied on most if not all AutoPostback controls, that replaces the script for a normal AutoPostback with one that also preserves focus:

private void fixAutoPostBack(TextBox tb)
if (!tb.AutoPostBack)
tb.AutoPostBack = false;
PostBackOptions options
= new PostBackOptions(tb, string.Empty)
TrackFocus = true,
AutoPostBack = true
if (tb.CausesValidation)
options.PerformValidation = true;
options.ValidationGroup = tb.ValidationGroup;
string onchange = string.Empty;
if (tb.HasAttributes)
onchange = tb.Attributes["onchange"];
if (!string.IsNullOrEmpty(onchange))
onchange = onchange.TrimEnd(';') + ";";
onchange += ClientScript
.GetPostBackEventReference(options, true);
tb.Attributes["onchange"] = onchange;

As you can see, the only thing I do differently from the normal AutoPostback code is to set TrackFocus to true.


Anonymous said...

This looks like a really useful and elegant approach to a common problem... but I've been trying and researching for over an hour now and still have no idea how to implement it! Everything I've tried returns the error: RegisterForEventValidation can only be called during Render();>.

A hint would be great.

Thanks for posting,


P.S. I do realise your post is over 4 years old.

Siderite said...

Oh, boy! I barely remember what I did there. The point of it was that you can look at the .Net sources, which have since been published for free on the Internet, but back then I was decompiling them using Reflector, and try to figure out what is going on.

Frankly, I think an ASP.Net site with autopostback it a terrible idea, but I was always about the solving of the problem and only then consider a different approach. But that's me. :)

Anonymous said...

Thanks.. and I agree... but in limited circumstances and for very specific purposes autopostback has its uses.

All the best,