64

On postback, how can I check which control cause postback in Page_Init event.

protected void Page_Init(object sender, EventArgs e)
{
//need to check here which control cause postback?

}

Thanks

Muhammad Akhtar
  • 51,913
  • 37
  • 138
  • 191

8 Answers8

119

I see that there is already some great advice and methods suggest for how to get the post back control. However I found another web page (Mahesh blog) with a method to retrieve post back control ID.

I will post it here with a little modification, including making it an extension class. Hopefully it is more useful in that way.

/// <summary>
/// Gets the ID of the post back control.
/// 
/// See: http://geekswithblogs.net/mahesh/archive/2006/06/27/83264.aspx
/// </summary>
/// <param name = "page">The page.</param>
/// <returns></returns>
public static string GetPostBackControlId(this Page page)
{
    if (!page.IsPostBack)
        return string.Empty;

    Control control = null;
    // first we will check the "__EVENTTARGET" because if post back made by the controls
    // which used "_doPostBack" function also available in Request.Form collection.
    string controlName = page.Request.Params["__EVENTTARGET"];
    if (!String.IsNullOrEmpty(controlName))
    {
        control = page.FindControl(controlName);
    }
    else
    {
        // if __EVENTTARGET is null, the control is a button type and we need to
        // iterate over the form collection to find it

        // ReSharper disable TooWideLocalVariableScope
        string controlId;
        Control foundControl;
        // ReSharper restore TooWideLocalVariableScope

        foreach (string ctl in page.Request.Form)
        {
            // handle ImageButton they having an additional "quasi-property" 
            // in their Id which identifies mouse x and y coordinates
            if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
            {
                controlId = ctl.Substring(0, ctl.Length - 2);
                foundControl = page.FindControl(controlId);
            }
            else
            {
                foundControl = page.FindControl(ctl);
            }

            if (!(foundControl is IButtonControl)) continue;

            control = foundControl;
            break;
        }
    }

    return control == null ? String.Empty : control.ID;
}

Update (2016-07-22): Type check for Button and ImageButton changed to look for IButtonControl to allow postbacks from third party controls to be recognized.

Marc Lopez
  • 561
  • 8
  • 15
J Pollack
  • 2,788
  • 3
  • 29
  • 43
  • 3
    Thanks for this... Perfect snippet for reuse. – Anthony Graglia Dec 22 '11 at 08:22
  • 1
    I have an advanced scenario where it is not working - http://stackoverflow.com/questions/14486733/how-to-check-whether-postback-caused-by-a-dynamic-link-button – LCJ Jan 23 '13 at 18:47
  • 5
    Doesn't this fail if there's more than one button or imagebutton? Looks like it would simply return the first one it found. – Mike Fulton May 02 '14 at 21:03
  • 7
    If there is more than one button and the button causing the postback has UseSubmitBehavior="True" then only this button will be included in HttpRequest.Form.AllKeys. If UseSubmitBehavior="False" then __EVENTTARGET will do the job. – user764754 May 21 '14 at 13:16
  • 2
    If the control that caused the postback is buried in a container, then you won't find it using the FindControl method on the page object w/o recursively searching into the child controls. – Daniel Przybylski Feb 11 '15 at 21:32
  • @DanielPrzybylski Not true, you can find the control in linear time using the names of the naming containers: http://pastebin.com/92Bqi3r1 – mbomb007 Aug 25 '16 at 18:54
  • This is very useful, however I think that the last line can return null if the control.ID is null(rare but possible), and I believe that your trying to avoid that, maybe it should be changed to something like "return control == null || control.ID == null ? String.Empty : control.ID;"? – David Rogers Jan 06 '17 at 16:32
  • Thanks for the code! I don't understand hovewer, why it is better to return the ID of the control instead of the control itself. I changed the method to return the control, simply to have the freedom, to check other properties as well instead of the ID (like is it a button or a checkbox). I can still get the ID of the control if I want. – pholpar Apr 20 '17 at 08:42
  • 1
    Thanks! Saved my butt, I'd built a page which required you to check the posting form to avoid blanking it out if it shouldn't be refreshed at that time. This made it possible to do so. I'm surprised there isn't a method like this provided by microsoft! – Philippe Haussmann Jun 24 '19 at 22:00
17

Here's some code that might do the trick for you (taken from Ryan Farley's blog)

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;
}
silvo
  • 4,011
  • 22
  • 26
  • 1
    I approve this code, I have used it for a while now. – Alex Mar 28 '16 at 17:23
  • This is the right code, my answer refers to PageUtility class, which I completely forgot it's a class I made with the method above. – Alex Aug 02 '16 at 20:04
11

If you need to check which control caused the postback, then you could just directly compare ["__EVENTTARGET"] to the control you are interested in:

if (specialControl.UniqueID == Page.Request.Params["__EVENTTARGET"])
{
    /*do special stuff*/
}

This assumes you're just going to be comparing the result from any GetPostBackControl(...) extension method anyway. It may not handle EVERY situation, but if it works it is simpler. Plus, you won't scour the page looking for a control you didn't care about to begin with.

tyriker
  • 2,290
  • 22
  • 31
  • This is a nice and simple trick. Helped in my situation, when just wanted to handle postback of some very specific controls. – Marcel Jan 25 '18 at 14:32
10

Either directly in form parameters or

string controlName = this.Request.Params.Get("__EVENTTARGET");

Edit: To check if a control caused a postback (manually):

// input Image with name="imageName"
if (this.Request["imageName"+".x"] != null) ...;//caused postBack

// Other input with name="name"
if (this.Request["name"] != null) ...;//caused postBack

You could also iterate through all the controls and check if one of them caused a postBack using the above code.

Jaroslav Jandek
  • 9,463
  • 1
  • 28
  • 30
  • Well then, you have to know all the controls that could have caused a postback and check if there is a value in the parameter collection (`Request[controlName]`). – Jaroslav Jandek Jul 04 '10 at 18:11
  • @JaroslavJandek Thank you for this answer. I had an instance where I needed to detect a button click during the page OnLoad event, but Request["__EVENTTARGET"] was empty for some reason (even though it wasn't with other controls causing postback. A check against Request[myButton.UniqueID] worked perfectly. +1 :) – KP. Jul 13 '12 at 14:01
4
if (Request.Params["__EVENTTARGET"] != null)
{
  if (Request.Params["__EVENTTARGET"].ToString().Contains("myControlID"))
  {
    DoWhateverYouWant();
  }
}
Eduardo
  • 693
  • 3
  • 9
  • 21
3

Assuming it's a server control, you can use Request["ButtonName"]

To see if a specific button was clicked: if (Request["ButtonName"] != null)

DOK
  • 32,337
  • 7
  • 60
  • 92
2

An addition to previous answers, to use Request.Params["__EVENTTARGET"] you have to set the option:

buttonName.UseSubmitBehavior = false;
dwitvliet
  • 7,242
  • 7
  • 36
  • 62
djmcghin
  • 61
  • 4
1

To get exact name of control, use:

    string controlName = Page.FindControl(Page.Request.Params["__EVENTTARGET"]).ID;
Nuno Ribeiro
  • 2,487
  • 2
  • 26
  • 29