views:

3264

answers:

6

If I have a property:

public list<String> names { get; set; }

How can I generate and handle a custom Event for arguments sake called 'onNamesChanged' whenever a name gets added to the list?

A: 

You'll need to not expose the list directly as a property and perhaps have your class implement IList or some such then have your event handler fire on the Add() method.

Jesse C. Slicer
That is so .NET 1.1 :) Like Marc Gravell said... lots of work, little benefit.
Maxim
+8  A: 

You should check out the System.ComponentModel.BindingList, specifically the ListChanged event.

David Mohundro
A: 

David Mohundro shows one approach; one other option is to inherit from Collection<T> and override the various methods:

class Foo {}
class FooCollection : Collection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        // your code...
        base.InsertItem(index, item);
    }
    protected override void SetItem(int index, Foo item)
    {
        // your code...
        base.SetItem(index, item);
    }
    // etc
}

Finally, you could create your own list (IList, IList<T>) from first principles - lots of work, little benefit.

Marc Gravell
+8  A: 

A BindingList is likely your best option as it has builtin change tracking and a variety of existing events you can use. Below is an example of exposing a custom event for Add which forwards to the BindingList event.


    class Example
    {
        private BindingList<string> m_names = new BindingList<string>();
        public IEnumerable<string> Names { get { return m_names; } }
        public event AddingNewEventHandler NamesAdded
        {
            add { m_names.AddingNew += value; }
            remove { m_names.AddingNew -= value; }
        }
        public void Add(string name)
        {
            m_names.Add(name);
        }
    }
JaredPar
Dang. I learn another new thing today. :)
Maxim
Whoa, I didn't know you could do that with events! Thats pretty slick!
Nicholas Mancuso
Very nice. I had no idea this was possible
Steve
+8  A: 

One alternative to BindingList is ObservableCollection - in this case you'd want to subscribe your own event handler to the CollectionChanged event and fire your event depending on the action.

Jon Skeet
Another up vote here. I still can't stop learning :)
Maxim
A: 

A non-orthodox approach might be using an AOP framework such as PostSharp to "weave" a handler before/after the accessor is called, which fires an event.

You create an external class which contains the pre and/or post handling code for when your property is accessed, check if the value of the property changed between pre and post, and raise an event.

Bear in mind that while taking the value for comparison (inside your handler code), you might get into an infinite loop (you call the property accessor, which calls the AOP handler, which calls the accessor and so on), so you might need to reflect into the class containing this property to attain the backing field.

Yoni Shalom