ASP.NET – 'PASSING PARAMETERS' IN BUTTON CLICK-HANDLER

August 10th, 2007 by comment

A recent posting to a technical mailing list I’m on asked how to pass a parameter to a button click-event handler. The programmer wanted to do the equivalent of this:

<asp:button ID="btnSubmit" runat="server" OnClick="Btn_Onclick(PARAM)" />

But, she knew this didn’t work, because the default signature of event handlers in ASP.NET is this:

void myBtn_OnClick(Object sender, EventArgs e)

So, she was stumped on how to pass some sort of argument to the event handler.

Now, there a certainly some kludges that would work, such as having a hidden form field which contains the ‘parameter’ value, and having the event-handler get the value that way. But surely, there’s a better way? Well, yes, of course there is! :)

This better way is to use the “CommandArgument” property on the button control. This property is directly accessable in the event handler. The added bonus is that you can write a single even-handler for all of your button clicks, and use the associated “CommandName” property to know which button fired.

So, now, in your aspx page, your button object will be declared thusly:

<asp:Button ID="test" runat="server" CommandArgument="MyVal" CommandName="ThisBtnClick" OnClick="MyBtnHandler" />

Then, in the OnClick handler, you can cast the sender object to the correct type, and get the values of
CommandName & CommandArgument. (You could make this even more generic and handle the OnClick event for different senders, but we’ll leave that for a later post! :)

void MyBtnHandler(Object sender, EventArgs e)
{
	 Button btn = (Button)sender;
          switch (btn.CommandName)
          {
                case "ThisBtnClick":
                    DoWhatever(btn.CommandArgument.ToString());
                    break;
                case "ThatBtnClick":
                    DoSomethingElse(btn.CommandArgument.ToString());
                    break;
           }
}

You can see that the switch statement uses the CommandName property to determine which button was clicked, and then can use the CommandArgument property passed in by the button click event.

Voila! You’ve “passed a parameter” to a button click-event handler!

[UPDATE] Thanks to Jim for pointing out some confusion in my sample code. I hope that this version is clearer.

Comments

24 Responses to “ASP.NET – 'PASSING PARAMETERS' IN BUTTON CLICK-HANDLER”

  1. Jim says:


    Nice article Kris. Concise and informative.

    I think it’s notable however that when using commandname and commandargument, do not use the onclick event in combination with them or you’ll get an ugly run-time error. This may be obvious to some more experienced developers but it wasn’t to me at first. Thanks again

  2. Kris says:


    Ah, I see the problem. In the click event handler shown in the article, I used CommandEventArgs instead of EventArgs, which, does indeed cause a problem if you use that handler with OnClick.

    I see that in my actual running code, I used EventArgs, and then cast the object to get the values. Then, the handler works with OnClick.

    I will update the article. Thanks.

  3. jeff says:


    Question. What is the point? Since you would have to change the code to do the right thing based on the parameters anyway, why not just use the button’s ID?

    Yes I guess you could code a few different things up ahead of time, and possibly change what the button does just by changing the HTML page, but I have trouble coming up with a reason to do this….

  4. Kris says:


    Well, the real power to this is that if you have objects on several pages that have the same on-click behavior, you can make a global method that is used by all pages in the app, to fire the method, w/o caring where the object is, or what its ID is.

    As usual in programming, there’s more than one way to something, and hardly ever is there a 100% “best way”. But it’s always nice to have alternatives, and to know when and where they can be taken advantage of.

  5. Bob says:


    Every developer should strive to make their code as efficient as possible. Your article provided me with some valuable insight and saved me numerous lines on a current project. Thank you!!!

  6. Kris says:


    I’m glad it was a help to you. I can’t count the number of times I’ve received help from some posting on the web, so I’m glad to ‘pay it forward’!

  7. Nathan says:


    Great post, I’m using it now. Thanks!

  8. Kris says:


    Super! Glad to help!

  9. Dusan says:


    I can go to sleep now, this was useful. :-) Just a question, since i’m not a programmer actually (I hope it won’t sound silly). How to pass more arguments if needed (can be avoided, yet sometimes perhaps not)?

  10. Kris says:


    Well, right off the top of my head, the first thing that comes to mind would be passing some sort of list of values, delimited in some way, such as commas: “x,y,z”. Then you’d still use the switch statement to determine the button sender, and in the case statement for that button you could parse out the separate parameters and use them however you need. (In .NET the parsing of the string could be done using the Split() method, splitting on the “,” delimiter, which would result in an array of the separate values.)

    There may be a better solution out there. Anyone? Anyone? Bueller?

  11. Dusan says:


    Yeah, i’v tried that without success. Even tough I’v e read about it in some other post and it works. I think I made a mistake in rearranging the dates afterwards, but it should work. Anyway, I’ve used “substring” function with IndexOf to find the comma separator.

    There was no other method mentioned anywhere in the web, which is quite weird, since it can be very useful to send more parameters. For example on updating database from the values of the selected datalist item.

    Now the solution was to make a separate hidden field outside datalist that is being updated on onchangetext event for example. Works great, but gets some additional code into the solution.

  12. Kris says:


    Ah, well, if you’re wanting to update a database, then bind all the controls to the database, so that when the form is submitted, they all update their respective database fields. Since you said you’re new to programming, you should check out the ASP.NET tutorials – and here’s a link to their data access tutorials: http://quickstarts.asp.net/QuickStartv20/aspnet/doc/data/default.aspx
    Good luck!

  13. Dusan says:


    Thxs, even tough i’m not that new. :-) I’m just not a programmer by my educations, so I rather say this in front then having someone afterwards saying “this is logical and simple”. :-)

    Speaking of that, I have a question that is bothering me sometimes and perhaps you have some insight into it – is sqldatasource much slower then objectdatasource? I mean – i’m using sqldatasource rather for it’s simplicity and none problems with later altering. Using datasets with xslt brought me some headache in past when changing it (if I have changed a query in the dataset, it brought out some problem inside xslt – most probably some VWDEV problem).

    But the question remains – is it really much better to use objectdatasource then sqldatasource? Do you have any idea on that? I’m actually considering switching it all to xml for reading data. But for now I don’t see any problems with sqldatasource. What’s your suggestion?

  14. Bill says:


    If there’s a ‘Click’ event, as well as an ‘onclick’ function, which gets performed first?

  15. Kris says:


    Dude – what are you doing looking at C# stuff on Christmas? ;)

    Anyway, here’s a couple of links on the page life cycle:
    http://msdn2.microsoft.com/en-us/library/ms178472.aspx
    http://www.15seconds.com/issue/020102.htm
    http://www.beansoftware.com/ASP.NET-Tutorials/Page-Life-Cycle.aspx

  16. Mark says:


    Thanks for the very informative article. It’s helping tremendously.

    It’s cool to discover “devchix” and the community of web savvy “chix”! This “dude” really appreciates it!

  17. sean says:


    There is another way to pass values (as many as you want) via a button click. You can add custom attributes to the button object via buttonName.attributes.add(“somAttributeName”, “someAttributeValue”)

    Then in your button event handler you cast the sender back to a button type and those attributes are available…

    Protected void SomeButton_Click(object sender, EventArgs e)
    {
    Button theButton = (Button)sender;
    string someAttribute = theButton.Attributes["someAttributeName"];
    }

    Hope that helps…

  18. Kris says:


    Sean, Yes you are absolutely right, and I’ve used that solution as well. Thanks for posting it, also.

  19. Adam says:


    While it’s a comment on a question asked a long time ago:

    Regarding using the commandname and commandargument instead of the ID I think the best reason is that they are easily changed during the programs running life whereas the ID is unique and should not change.

    Additionally, and the reason I found this, is the idea of buttons created dynamically at runtime. I’m creating a quasi-shopping application right now and need to create “purchase” buttons that all do the same thing but reference different item identifiers. These buttons are created dynamically inside of the datalist, so I actually don’t even know the true id of them when they come out. This is compounded even further by it being a DNN site, so the true ID in a source view of the delivered page gets really out of whack. Using the commandargument like this I can easily databind it to a unique ID in the resultset.

    What I picked up to extend it from here (mostly due to being a novice programmer) is the idea of extending it to the commandname and using a single handler. I need to map out that versus the separate handlers I had in mind to see what works best in this situation, but each item will need to have three or four possible actions based on separate buttons.

  20. Uzhiel says:


    thanks

  21. Tyrone says:


    Nice one, worked a treat!

  22. Tyrone says:


    Nice one, worked a treat! Thanks!

  23. James says:


    Thank you for this tutorial. It was exactly what I needed to pass a value into an image button event handler in my code behind. DevChix rocks!

  24. John says:


    It was very useful! Many Thanks!

Got something to say?


cheap research papers