About Me

Professional Practical HumanBeing

Tuesday, November 16, 2010

Determining the Control that Caused a PostBack

Many times you might need to perform some action on an ASP.NET postback based on the control that caused the postback to occur. Some scenarios for this might include a form with many regions, each having it's own CustomValidator and the ability to perform a postback when a button for the section is clicked. Another scenario might be to set focus back to the control that caused the postback.

There are two parts to the process of determining which control caused the postback. First, you access the __EVENTTARGET element of the form. If you've ever looked a the anatomy of an ASP.NET page (and if you haven't why are you reading this?), you'll notice that a hidden input tag is added to the form named __EVENTTARGET. This hidden input is set to the name of the control that was clicked in the __doPostBack JavaScript function and then the form is submitted. Looking at how the server controls are rendered as HTML tags you can see that the __doPostBack function is called by the controls to cause a postback, passing the name of the control to the function. You can access this hidden input from your code-behind as it is submitted with the form and can be found in the Params or Form collections. This the first part to getting the control that caused a postback. Once you have the name you can get a reference to the control via FindControl and use it as needed

string ctrlname = page.Request.Params.Get("__EVENTTARGET"); if (ctrlname != null && ctrlname != string.Empty) {     return this.Page.FindControl(ctrlname); }

This will work, but you'll soon find that something is missing. Although this will work for CheckBoxes, DropDownLists, LinkButtons, etc, this does not work for Button controls. This is where the second part comes in. But why is it that this doesn't work for Buttons? If you again take a look at how the server controls render as HTML, you'll see that the buttons do not call the __doPostBack Javascript function so the __EVENTTARGET is never set. Instead, the Buttons render as simpleinput type=“submit” tags. All the button does is cause the form to submit. That's it. However, you can still get to it, just in a different way. Since the button (or input) is what causes the form to submit, it is added to the items in the Form collection, along with all the other values from the submitted form. It is important to note, that other input type=“submit” tags on the form are not added to the Form collection unless it was the one that caused the form to submit. If you were to look in the Form collection for anything that is a button then that will be what caused the postback (assuming that it was a button that caused the page to submit). If you first check the __EVENTTARGET, then if that is blank look for a button in the Form collection then you will find what caused the postback. The complete code follows:

public static Control GetPostBackControl(Page page) {     Control control = null;      string ctrlname = page.Request.Params.Get("__EVENTTARGET");     if (ctrlname != null && ctrlname != string.Empty)     {         control = page.FindControl(ctrlname);     }     else     {         foreach (string ctl in page.Request.Form)         {             Control c = page.FindControl(ctl);             if (c is System.Web.UI.WebControls.Button)             {                 control = c;                 break;             }         }     }     return control; }

This method takes a parameter which is a reference to the Page, it then uses that to look for the control that caused the postback. You can easily use this as follows

Control c = PageUtility.GetPostBackControl(this.Page); if (c != null) {     //... }

You can now do some specific action based on the control that caused the postback or use an earlier post I made to set focus to the control.

LINQ Version :-

///

/// Gets the control which caused the postback.
///


/// The page in which the postback occurs. Most like will be "this.Page".
/// The control which caused the postback and null if the control was not found.
public static Control GetPostBackControl(Page page)
{
string eventTarget = page.Request.Params["__EVENTTARGET"];
if (!string.IsNullOrEmpty(eventTarget))
{
return page.FindControl(eventTarget);
}
else
{
// If __EVENTTARGET is null, the postback control is a button type. Use LINQ
// to query the Request's form variables order to find the button control.
var postbackButton = (from x in page.Request.Form.AllKeys
where page.FindControl(x) is Button || page.FindControl(x.Substring(0, x.Length - 2)) is ImageButton
select (x.EndsWith(".x") ? x.Substring(0, x.Length - 2) : (x.EndsWith(".y") ? x.Substring(0, x.Length - 2) : x))).FirstOrDefault();

return (!string.IsNullOrEmpty(postbackButton) ? page.FindControl(postbackButton) : null);
}
}

Source :-

http://ryanfarley.com/blog/archive/2005/03/11/1886.aspx

No comments:

Post a Comment