RSS 2.0 Feed
RSS 2.0


Atom 1.0 Feed
Atom 1.0

  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 simple input 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.




                   



Leave a comment below.

Comments

  1. Alexander 3/22/2005 12:52 AM
    Gravatar
    That article helped me to solve a problem.

    Thank you.
    Alexander
  2. isas 3/28/2005 2:46 PM
    Gravatar
    I have a imagebutton and this doesn't work for that.
  3. Ben Parker 4/5/2005 6:11 PM
    Gravatar
    Legend. Thanks
  4. Rick 4/12/2005 10:35 AM
    Gravatar
    " I have a imagebutton and this doesn't work for that. "

    We re-wrote this in VB and had to deal with imagebuttons too. I will insert the code in VB, and you can convert it to C#, because i'm hungy, and its lunch time, and I don't feel like taking the time to do it myself.

    foreach (string ctl in page.Request.Form)
    {

    ''''''''''''''''''''Begin VB Code''''''''''''''''''''''''''''
    if ctl.EndsWith(".x") or ctl.EndsWith(".y") then
    ctl = ctl.substring(0,ctl.length-2)
    end if
    ''''''''''''''''''''End VB Code''''''''''''''''''''''''''''


    Control c = page.FindControl(ctl);
  5. Rick 4/12/2005 10:36 AM
    Gravatar
    Also note, this will not work if you (for some unknown reason) name your control "MyControl.x" or "MyControl.y"

    Im sure you knew that though
  6. opello 4/19/2005 1:40 PM
    Gravatar
    Also note that this doesn't work for arrays of controls that are created dynamically (or controls that are created dynamically for that matter).
  7. Harnek 4/20/2005 2:28 PM
    Gravatar
    Its Great Thanks
  8. Amol K 5/1/2005 10:38 PM
    Gravatar
    Excellent
  9. crg 5/10/2005 12:09 PM
    Gravatar
    It also doesn't work if you have multiple buttons on your page. It's useless.
  10. toji a mathew 5/14/2005 3:31 AM
    Gravatar
    how to get a selected index of a dropdownlist added in a placeholder control
  11. arkus 5/18/2005 5:16 AM
    Gravatar
    this is not usefully when there are multiple buttons
  12. Imran 5/23/2005 9:58 PM
    Gravatar
    THANKS A LOT FOR A NICE PIECE OF WORK
  13. jairo 7/3/2005 5:08 PM
    Gravatar
    Very useful pal, thanx a lot
  14. David Peck 7/18/2005 6:26 AM
    Gravatar
    Serious love from all over this post, it would seem
  15. GPF 7/20/2005 4:17 AM
    Gravatar
    If you have dynamically added controls then add these controls on page init event. Otherwise you may even loose your events assigned to these controls.
  16. Captain's Blog 9/2/2005 4:55 PM
    Gravatar
  17. Jay Parker 10/11/2005 6:21 AM
    Gravatar
    I found this very helpful. It solved my problem. Thank you!
  18. dhillman 10/18/2005 11:04 AM
    Gravatar
    RadioButtonList controls also pose some problems. The value returned by

    page.Request.Params.Get("__EVENTTARGET")

    is not really the name of the control. By examining the value returned, I am able to extract the real control name, and then pass that to the page.FindControl method.

    Is there a better way to get the name of the real control?

    And the value returned by page.Request.Params.Get("__EVENTTARGET")
    seems to be constructed differently depending upon the control type. Are there any rules to how this value is constructed?

    thanks for the assistance
  19. Surendra 12/8/2005 1:00 AM
    Gravatar
    This really a good article but how do u differentiate with refresh.
    what i mean to say if u refresh teh page it show the name of that control that caiused teh post back earlier.can we avoid that?
  20. Bob 12/8/2005 12:02 PM
    Gravatar
    Nice but it only returns the first button of the page...
  21. Dave 1/31/2006 8:20 PM
    Gravatar
    This is great....It is NOT Useless....the very FIRST button you encounter in the for each loop IS the button that caused the postback even if you have a buttload of buttons on the page.

  22. Ryan Farley 2/1/2006 6:10 AM
    Gravatar
    Thanks Dave,

    It's always worked for me too ;-) (which is why I posted it in the first place!)

    -Ryan
  23. Mayur Joshi 2/22/2006 3:42 PM
    Gravatar
    I am still confuse what will happened if there is more than one button control on the web form. How ‘else’ part of GetPostBackControl method will work?

    Mayur
  24. wombat 3/3/2006 12:49 PM
    Gravatar
    Mayur,

    I think, the way html post works is that only the button that causes the form to submit is posted back.

    On another front, i've seen other implementation, whick involves extending the stock standard button, and attached a piece of javascript to it to set the EVENTTARGET hidden field.

    wombat
  25. Abhrajit 4/6/2006 12:58 AM
    Gravatar
    How do I check for a Datagrid edit column edit link that caused the post back?
  26. Anthony Walsh 4/13/2006 7:38 PM
    Gravatar
    Thank you, thank you, thank you... This is exactly what I was looking for!
  27. Dave Bacher 4/20/2006 6:31 AM
    Gravatar
    Surendra,

    When you hit refresh, ASP.NET will receive the same information that it received the first time. In order to differentiate a refresh from the most recent postback, add a GUID to the viewstate.

    Then whenever you successfully process a postback event, you write the GUID from the viewstate to session. At the start of the routine that processes the postback event, you check to see if the GUID in viewstate matches the GUID in session. If the two match, then it was a refresh browser side. If the two are different, then it is a fresh postback.

    You can use a counter, prng, etc. to generate the numbers -- GUID is just excessively convenient for this purpose. :-)
  28. Geoff Martin 4/26/2006 11:58 AM
    Gravatar
    I have solved A BIG problem with this!!!! thanks a lot, you're my hero!!!!!
  29. Bubba 5/2/2006 3:52 AM
    Gravatar
    You rock dude! :) Thanks!
  30. GT 5/31/2006 11:36 AM
    Gravatar
    I use the "sender" object parameter in the PostBack Event method.

    void ButtonClick(object sender, System.EventArgs e)
    {
    Control ctrl = (Control)sender;
    }

    Of course if you can get the type of the control and cast it to get the controls properties as well.
  31. Dahlsim 8/10/2006 9:35 AM
    Gravatar
    Which is fine if you don't need to know the triggering control until you are in the event handler but what if you need to know earlier such as in Page_Init?
  32. Dave 9/6/2006 2:25 PM
    Gravatar
    Can someone PLEASE post this entire Function in VB? Thanks in advance.
  33. Johny Cash 9/17/2006 1:26 PM
    Gravatar
    C# version which works with ImageButtons as well

    private Control getClickedButton()
    {
    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 = null;

    if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
    {
    c = Page.FindControl(ctl.Substring(0, ctl.Length - 2));
    }
    else
    {
    c = Page.FindControl(ctl);
    }

    if (c is System.Web.UI.WebControls.Button || c is System.Web.UI.WebControls.ImageButton)
    {
    control = c;
    break;
    }
    }
    }
    return control;
    }
  34. Sandeep 10/9/2006 10:58 PM
    Gravatar
    Hi,

    Can i on Page_Load() determine which control caused the PostBack? Not only just the type of Control, but the Value of the control.

    Thanks in advance.
  35. Ryan Farley 10/10/2006 6:29 AM
    Gravatar
    Sandeep,

    That is exactly what this article describes.

    -Ryan
  36. K 11/7/2006 10:02 PM
    Gravatar
    Nice!!! Been Googling on this one for a while.....
  37. Another programmer 11/9/2006 6:55 AM
    Gravatar
    Thanks and God Bless You.
  38. Paul Reid 12/13/2006 2:55 PM
    Gravatar
    Or, more efficiently,

    if (Request.Form[Button1.UniqueId] == Button1.Text)
    // button1 pressed
    else if (Request.Form[Button2.UniqueId] == Button2.Text)
    // button2 pressed
    else ...

    Unless you have dozens of buttons, this is efficient and clean.

    This avoids the foreach (a hashtable of the Request objects has already been built) and especially the multiple FindControls which are rather inefficient (and occasionally flaky in my experience).
  39. Abhishek 12/14/2006 2:15 AM
    Gravatar
    Hi,
    This article is good. But in my case i have 4-5 buttons in a ascx( user control) file. I click on any of those button post back is caued.
    When i try to identify that which button actaully caused the postback using that "__ EventTarget" i get the name of that ascx file.

    But i am not able to find out which button actaully caused a postback.

    Please help me out with this..... thanks in advance
  40. Pericles Rocha 1/8/2007 11:59 AM
    Gravatar
    I have two buttons on my form and "GetPostBackControl" works great with me... great work, this is VERY usefull, thanks very much...
  41. upalsen 1/18/2007 12:31 AM
    Gravatar
    thanks a lot. I was just looking for this...
  42. Chad Baker 1/20/2007 10:30 AM
    Gravatar
    Ryan, you ARE the man. When I try to find code on the web, the people posting solutions are either freaky brilliant OR concise and to the point, but rarely both. Big ups, thanks!
  43. Ronnie 1/27/2007 1:24 PM
    Gravatar
    I tried to use this code to set focus on a User Control created in a row of datagrid. I got the control id which causes post back. But then it could not load the page as it could not find the control during rendering the page. Any suggestions!!!
  44. Mark 3/27/2007 1:48 AM
    Gravatar
    Hi,

    Great Article, I was wondering if there is an approach where I can find the button which has caused the event in the Application_PreRequestHandlerExecute handler in the Global.asax

    My aim is to create a generic tracer where I track a users last 10 actions in the aim of when there is an application error we can keep a track of what the user has done up until that point.

    I am using .NET 1.1.

    Any help would be great
  45. Chris 4/11/2007 8:47 AM
    Gravatar
    Thanks for the code - this works great if you have a textbox with autopostback=true.

    However, if I have a textbox with autopostback=false, and hit enter, it still posts back if it's the only textbox on the page. In this case, there doesn't seem to be a way to determine the cause of the postback.

    Any thoughts?
  46. Travis J. May 5/30/2007 9:34 AM
    Gravatar
    Thanks a million! This is soooooo basic, I was wondering why the heck it was so hard to do.....
  47. Waleed 7/15/2007 6:30 AM
    Gravatar
    This is exactly what I was looking for .. thanks a lot
  48. Dave 7/19/2007 9:52 AM
    Gravatar
    Thanks! You saved my last piece of hair!
  49. Francisco 8/2/2007 2:42 PM
    Gravatar
    Thanks!
  50. Jonny Upstart 8/14/2007 7:07 AM
    Gravatar
    Nice. I've found this elsewhere, but what I have not found elsewhere is what Paul Reid posted above:

    (if (Request.Form[Button1.UniqueId] == Button1.Text)

    That is much nicer than running through a control collection, especially since I've noticed some peculiar behaviour doing that with a formview.

    Anyway, the necessity of all this at least in my case is that I am trapping a button or linkbutton's event in the Page_Init to then create dynamic controls. If I wait for that button's normal event, it occurs after Page_Load, which is too late for the wiring in the dynamic controls to work. Big pain and not elegant, but hey...
  51. Milan Rawat 8/24/2007 9:40 PM
    Gravatar
    Great Post Bussy.. simply awesome.............
  52. Thai Nguyen 8/30/2007 4:06 PM
    Gravatar
    Thank you, Ryan, for this code - works great!

    Does anyone know how to convert this line of code

    "c is System.Web.UI.WebControls.Button" to Visual Basic?


    Below is what I can convert to Visual Basic
    ---- VB----
    Public Function GetPostBackControl(ByVal myPage As Page) As Control
    Dim ctl As String
    Dim myControl As Control

    Dim ctrlname As String = Page.Request.Params.Get("__EVENTTARGET")
    If (ctrlname <> String.Empty) Then
    myControl = Page.FindControl(ctrlname)
    Else
    For Each ctl In Page.Request.Form
    Dim c As Control = Page.FindControl(ctl)
    myControl = c
    Next
    End If

    Return myControl
    End Function

    --- End VB -----
  53. JimboM 9/18/2007 4:01 PM
    Gravatar
    Translating "c is System.Web.UI.WebControls.Button" to Visual Basic? Simple:

    If TypeOf c Is System.Web.UI.WebControls.Button Then
    ---
    End If
  54. Wole 11/6/2007 6:31 AM
    Gravatar
    Hi,

    This code was exactly what I was looking for. Picture the scenario: I check (from a database) if a user's session has expired in the Page Load event. If their session has expired, I display an appropriate message and redirect to a Login page.

    However, if the user clicks the Logout button and their session has expired in the meantime, ..., you guessed it, they're told they can't logout because they have been logged out. duh!

    Problem--Logout button click event doesn't run until after the Page Load event has run.
    Solution--Use this code int Page Load event to check if the Logout button was clicked, then regardless of whether their session has expired or not, just silently log them out.

    Thanks to Ryan and Paul Reid's code, I was actually able to cut it all down to one line of code (this will work if you know the name of your button and it's a Button or ImageButton [may also work for other controls as well; I don't know...haven't tested other controls]):

    bool LogoutButtonPressed = (Page.Request.Form["btnLogout"] != null || Page.Request.Form["btnLogout.x"] != null);
  55. Marcus Götling 11/14/2007 8:32 AM
    Gravatar
    Awesome!
  56. pakornss 11/27/2007 11:48 PM
    Gravatar
    For ASP.NET 2.0: (with AJAX Extension 2.0)

    ++++++++++++++++++++++++++++++++++++++++++++++

    public static Control GetPostBackControl()
    {
    Page page = (HttpContext.Current.Handler as Page);
    string ctrlname = ScriptManager.GetCurrent(page).AsyncPostBackSourceElementID;

    Control control = page.FindControl(ctrlname);
    return control;
    }

    ++++++++++++++++++++++++++++++++++++++++++++++
  57. Sarah 12/3/2007 3:15 PM
    Gravatar
    I'm trying to figure out this exact same thing in javascript on the client-side.(I have already used this technique server-side and it works.) But I need my client-side validators to also be able to tell which button was clicked (between two buttons) also. I can't figure out how to access the same data structures on the client side. Can you provide any insight?

    Thanks,
    Sarah
  58. Alex 1/24/2008 9:35 PM
    Gravatar
    Thank you!!!
  59. Steve 4/30/2008 3:07 PM
    Gravatar
    Thanks for this, perfect code!
  60. Anchal Jain 5/1/2008 12:30 AM
    Gravatar
    Thanks, was looking for this only !!! Great code
  61. Qaiser Mehmood Mughal 6/11/2008 5:35 AM
    Gravatar
    Thank you.
    Its very helping.........
    nice....

    Regards
    ----------
    QMM
  62. Arun T 8/12/2008 10:26 AM
    Gravatar
    Excellent article! Definitely a life saver in my case. Thanks Ryan!
  63. László Siroki 8/26/2008 8:33 AM
    Gravatar
    In ASP.NET 2.0, you can set the behavior of the button by the UsesubmitBehavior property. If it is set to false, the __doPostBack will be used by the button.
  64. sreeni 8/29/2008 4:26 PM
    Gravatar
    I have Buttomn in UserControl ,This code is not recognizing those buttons ,Help me out.

    Thank you
  65. chirdeep 9/10/2008 4:53 AM
    Gravatar
    Great, I helped me a lot and is exactly what I wanted.
  66. NIRMAL mehta 9/25/2008 12:21 PM
    Gravatar
    Your are Damn Genuis as you solved my problem
  67. Daniel Herrera D. 10/6/2008 4:13 PM
    Gravatar
    When i do postback with a Button, only this control goes in the request so the "foreach" finds it without any problem.

    I used the .ID field to identify my specific button.

    Thanks a lot for the article.
  68. nushahi 11/3/2008 1:29 AM
    Gravatar
    we i put linkbutton in template field in grid view the linkbutton not go to event click why ??
  69. Savas Karaduman 11/25/2008 12:45 PM
    Gravatar
    Very nice article. I solved my problem.
  70. George 2/25/2009 4:57 PM
    Gravatar
    very helpful information. you should start writing books
  71. Joe 2/28/2009 12:18 PM
    Gravatar
    Works great, clean code
  72. Ludvig 3/19/2009 1:59 AM
    Gravatar
    Great article, it solved my problem!
  73. Latha 5/8/2009 5:36 AM
    Gravatar
    Nice article , It solved my problem.

    Thank You Very Much.
  74. slade73 6/9/2009 9:35 AM
    Gravatar
    Thanks!
  75. Amar 6/24/2009 1:05 PM
    Gravatar
    Was Useful.
    Thanks.
  76. Martin 7/1/2009 5:22 AM
    Gravatar
    Brilliant! Absolutely Brilliant!

Leave a comment

Please be polite and on topic. Your e-mail will never be published.

Please add 8 and 6 and type the answer here:



 

News


Also see my CRM Developer blog

Connect:            

Sponsor

Sections