We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Is it possible to handle and raise events through extension methods?

Unimatrix_001
on
Medium Priority
200 Views
Last Modified: 2012-05-11
Hello,

Please see the attached code.

You'll notice that CObject has an event that is raised when the field is changed, however what I'm wanting to achieve is to be able to handle this event using an extension method in the CObjectCollectionExtensions class and then raise this event from the CObjectCollectionExtensions class so that rather than other classes having to subscribe to the events of the individual CObject class, they can simply subscribe to the object of CCollection<CObject>. So I could have something like:

public class TestClass {

	public void TestMethod(){

		CCollection<CObject> mObjectCollection=new CCollection<CObject>();

		mObjectCollection.FieldChangeEventHandler+=new mObjectCollection.FieldChangeEventHandler(FieldChangeHandler);

	}

	public void FieldChangeHandler(CObject aSender) {
		//Do things with the sender.
	}

}

Open in new window


Is there a nice way of achieving this?

Thanks,
Uni
public class CObject {

	public delegate void FieldChange(CObject aSender);
	public event FieldChange FieldChangeEventHandler;

	private int mField;

	public int GetField(){
		return mField;
	}

	public void SetField(int aField){
		mField=aField;
		if(FieldChangeEventHandler!=null)
			FieldChangeEventHandler(this);
	}

}



public class CCollection<T>{

	private List<T> mList;

	public CCollection(){
		mList=new List<T>();
	}

	public void Add(T a){
		mList.Add(a);
	}

	public void Remove(int aIndex){
		mList.RemoveAt(aIndex);
	}

	public int GetNumberOfObjects(){
		return mList.Count;
	}

	public T GetObject(int aIndex){
		return mList[aIndex];
	}

}



public static class CObjectCollectionExtensions{

	public static CObject GetObjectByField(this CCollection<CObject> aCollection, int mField){
		for(int tIndex=0;tIndex<aCollection.GetNumberOfObjects();tIndex++){
			if(aCollection.GetObject(tIndex).GetField()==mField)
				return aCollection.GetObject(tIndex);
		}
		return null;
	}

}

Open in new window

Comment
Watch Question

Senior Engineer
CERTIFIED EXPERT
Top Expert 2010
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview

Author

Commented:
Appreciate the reply - thanks. Somehow I didn't think extensions would help here... Oh well, thanks anyways. :)

Uni
Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
You know, you could just have CCollection<CObject> subscribe to each CObject's FieldChange event as they're added to the collection, in CCollection<CObject>.Add() (and likewise do the inverse in CCollection<CObject>.Remove()), then CCollection<CObject> will handle each CObject's FieldChange with the same private member method, and can in turn raise it's own event.

Author

Commented:
Hm, it's not quite as tidy as I had hoped - I think I'll just stick to inheritance... I'm just creating a new collection class and inheriting from the CCollection class - makes the code a little clearer as well I suppose.

Thanks for your help,
Uni
Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
e.g.:

class MyObject
{
	private int _myField;
	public event EventHandler FieldChanged;

	protected virtual void OnFieldChanged(EventArgs e)
	{
		if (FieldChanged != null)
			FieldChanged(this, e);
	}

	public int MyField
	{
		get { return _myField; }
		set
		{
			_myField = value;
			OnFieldChanged(new EventArgs());
		}
	}
}

class MyCollection : Collection<MyObject>
{
	public event EventHandler MemberFieldChanged;

	protected override void InsertItem(int index, MyObject item)
	{
		item.FieldChanged += new EventHandler(item_FieldChanged);
		base.InsertItem(index, item);
	}

	protected override void RemoveItem(int index)
	{
		Items[index].FieldChanged -= item_FieldChanged;
		base.RemoveItem(index);
	}

	protected virtual void OnMemberFieldChanged(EventArgs e)
	{
		if (MemberFieldChanged != null)
			MemberFieldChanged(this, e);
	}

	void item_FieldChanged(object sender, EventArgs e)
	{
		OnMemberFieldChanged(new EventArgs());
	}
}

Open in new window

Author

Commented:
Heh, that's next to identical to what I've got here! :)
Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
Great minds think alike.

Incidentally, I believe the latest Framework has some built-in classes that achieve this effect - I'm not a big database guy so I'm not too familiar with them, but you can have a look at http://msdn.microsoft.com/en-us/library/ms668604.aspx for a starting poing (and/or Google "observable collections").

Author

Commented:
Can't say I've heard of them before - I'll have a bit of a look into them - seems I may be re-inventing the wheel...
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.