By now everyone should have at least heard of the "mx.utils.Delegate" class that was included in the Flash 7.2 updater. This post is not intended to explain the Delegate class, but rather, here's a simple little trick showing how to use Delegate to pass additional information to generic event handlers.
Here's the scenario: A user is presented with two buttons. Each button increments a value by a different amount (either 1 or 5) when the button is pressed.
Programming this interaction is easy enough - we simply create two functions, incrementBy1 and incrementBy5, and proxy the events to the appropriate function. Part of the code for that might look like this:
btn1.addEventListener("click", Delegate.create(this, onIncrement1));
btn2.addEventListener("click", Delegate.create(this, onIncrement2));
However, this solution isn't ideal. We've created two distinct increment functions that perform basically the exact same task. In this situation, what we really want to do is create a single increment function, and pass the amount to increment as a parameter.
We can mimic this behavior by proxying both of the events to the same onIncrement function, examine the event's target's name property to figure out which button was pressed, and then increment by the value associated with that button. The code for the new onIncrement might look like this:
function onIncrement(eventObj) {
var which:Number;
which = parseInt(eventObj.target._name.substr(3));
switch(which) {
case 1: total += 1; break;
case 2: total += 5; break;
}
trace(total);
}
However, the problem with that is we're back to the reason that we wanted to proxy events in the first place! We don't want a generic event handler to have to determine where the event came from. Instead, we want the event handler to just "do it's thing" without worrying about context.
We can accomplish this by leveraging Function objects in Flash. Whenever you call Delegate.create, a function is returned. We can stuff properties into that Function object, and then access those properties from within the event handler by using the arguments.caller scope.
You can see this technique in action in the following complete code sample:
// 1) create a blank fla, drag a v2 button to the
// stage then delete the button instance so that
// the button only resides in the library.
// 2) paste this code on frame 1 and test movie
import mx.utils.Delegate;
import mx.controls.Button;
function init() {
// create and place our buttons
createClassObject(Button, "btn1", 1, {label:"plus 1"});
createClassObject(Button, "btn2", 2, {label:"plus 5", _y: btn1._y+btn1.height});
// both buttons use the same onIncrement event
// handler - but the handler behaves differently
// based on the step value set
var f = Delegate.create(this, onIncrement);
f.step = 1; // btn1 steps up by 1
btn1.addEventListener("click", f);
f = Delegate.create(this, onIncrement);
f.step = 5; // btn2 setps up by 5
btn2.addEventListener("click", f);
// initialize our running total
total = 0;
}
// generic increment function used as
// event handler for the buttons
function onIncrement() {
// grab the step property from the
// delegate function we created, and use
// that as the increment value
total += arguments.caller.step;
trace(total);
}
init();
By using a generic increment function and using what I'll call "pseudo-parameters" we can easily add new buttons with different increment (or decrement) values. This enables us to easily reuse the code we already have and make maintenance easier.
In summary, we can pass parameters to a generic event handler using Delegate.create by stuffing data into the Function object returned by the create call and then using the arguments.caller scope in the event handler body to access that data.
More information on the Delegate class can be found here: Proxying Events with the mx.utils.Delegate Class

Sweet! Thanks for sharing!
If you prefer a little more type-safety, and you don't mind using my "unofficial" delegate implementation (http://www.peterjoel.com/blog/index.php?archive=2004_08_01_archive.xml), you can create specific subclasses of EventDelegate for a task, or a more general-purpose subclass, that allows properties to be stored for generic purposes.
To use your example, something more generic would be along the lines of:
import com.peterjoel.events.EventDelegate;
class ParamDelegate extends EventDelegate {
public var params:Array;
function ParamDelegate(targ:Object, func:Function){
super(targ, func);
params = [];
}
}
which you can use like this:
var f:ParamDelegate = new ParamDelegate(this, onIncrement);
f.params[0] = 1;
btn1.addEventListener("click", f);
f = new EventDelegate(this, onIncrement);
f.params[0] = 1;
btn2.addEventListener("click", f);
function onIncrement(event:Object, delegate:ParamDelegate){
total += delegate.params[0];
}
For those of you who would rather use a custom class as a solution, check out Joey Lott's article here:
http://www.person13.com/blog/archives/000030.html
I have used this method and it works great. How does one change the scope when dealing with ASBroadcaster like in the Tween class. I am trying to send a parameter with the onMotionFinished event with no luck.
var f = Delegate.create(this, onMotionFinished);
f.myParam = "hello";
myTween.addListener(f, "onMotionFinished");
Does not seem to work for me.
NM, I got it working fine with the custom class wrapper.
Thanks
doesn't this setup sort of contradict the main reason for using Delegate in the first place, namely to avoid creating an activation object for the function that assigns the callback?
since you store the Delegated function in local var 'f', all the local vars in init() (in this case, only 'f') will remain in memory until they're no longer pointed to, namely when the btn EventListeners are removed....
is this true? not entirely sure about it.