[Mono-list] late linking & dynamic invocation ...

Gonzalo Paniagua Javier gonzalo@gnome-db.org
Wed, 26 Jun 2002 22:45:04 +0200


* [ Michael Meeks <michael@ximian.com>
* Wed, 26 Jun 2002 18:10:25 +0200 ]
> 	b) A way to handle delegates that is elegant; eg. I wish to
> 	   implement the following (or similar):
> 
> 	private void sizeAllocate (Widget w, Allocation a,
> 				   Object closure);	
> 	...
> 		w.addHandler ("size_allocate", sizeAllocate, myObject);
> 
> 	   I don't mind doing a (redundant) new Foo (sizeAllocate), and 
> 	I can see how you can do this with loads of delegates: new 
> 	DelegateWidgetAllocation (sizeAllocate) eg. but I don't want to
> 	go around typing the method signature twice - once in declaring 
> 	it, and once in a delegate allocation scheme.

You can use EventHandlerList if you find it more convenient:

	private object SizeAllocateEvent = new object ();
	private EventHandlerList _evList;
	...
	
	protected EventHandlerList Events
	{
		get {
			if (_evList == null)
				_evList = new EventHandlerList ();
			return _evList;
		}
	}

	public event EventHandler SizeAllocate
	{
		add { Events.AddHandler (SizeAllocateHAndler, value); }
		remove { Events.RemoveHandler (SizeAllocateHAndler, value); }
	}

        void OnSizeAllocate (EventArgs e)
        {
                if (_events != null) {
			EventHandler eh = (EventHandler) Events [SizeAllocateEvent]);
			if (eh != null)
				eh (this, e);
		}
	}

Now, to add an event, you do:

	SizeAllocate += new EventHandler (your_method);

then you implement a subclass of EventArgs (is, SizeAllocattionArgs) that deals with
the arguments you need for the event.

public class SizeAllocationArgs : EventArgs
{
	public SizeAllocationArgs (Widget w, Allocation a, object closure)
	{
	...
	}

	...
	properties for accesing widget, allocation, ...
	...
}

and now, to invoke the delegates:

	OnSizeAllocate (new SizeAllocationArgs (w, a, closure));

and last, but not least:
	public void your_method (object sender, EventArgs e)
	{
		SizeAllocationArgs s = e as SizeAllocationArgs;
		if (s == null){
			...
			e was null or not an instance of
			SizeAllocationArgs
			...
		}
		....
	}
	
Was something like this what you wanted?
If not, don't say that i haven't tried :)

Cheers!

- Gonzalo
-- 
Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
http://www.gnome-db.org/~gonzalo/