Calanus
Calanus

Reputation: 26287

Creating an event that triggers when a List is updated

I've got a static class (DataFormSubject) that holds a generic List object, as follows:

private static List<DataForm> dataForms = new List<DataForm>();

Other classes that rely on this list need to be told when the list is updated, so I created a custom event, and associated methods that could trigger when an item is added or removed, as follows:

    public delegate void DataFormsUpdatedHandler(object sender);
    public static event DataFormsUpdatedHandler DataFormsUpdatedEvent;

    public static void AddDataForm(DataForm df)
    {
        dataForms.Add(df);
        if (DataFormsUpdatedEvent != null)
            DataFormsUpdatedEvent(df);
    }

    public static void RemoveDataForm(DataForm df)
    {
        dataForms.Remove(df);
        if (DataFormsUpdatedEvent != null)
            DataFormsUpdatedEvent(df);
    }

The List is available from the static class via a property, as follows:

   public static List<DataForm> DataForms
    {
        get { return dataForms; }
        //set { dataForms = value; }
    }

But the problem here is that the client can now bypass the update event by accessing the property and doing a direct add or remove on the class! E.g.

     DataFormSubject.DataForms.Add(new DataForm);

How can I prevent this, or is there a better way of acheiving what I want? Ideally what I would like is an update event on the List class that observers can subscribe to!

Upvotes: 2

Views: 2022

Answers (3)

gcores
gcores

Reputation: 12656

Don't show an IList from the static class, only show an Enumerable:

public static IEnumerable<DataForm> DataForms
{
    get { return dataForms; }
    //set { dataForms = value; }
}

This way all changes must be done through your class

Upvotes: 0

Noldorin
Noldorin

Reputation: 147381

You want to look into using an ObservableCollection for such a purpose. See this MSDN article to get started.

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1063198

Consider using BindingList<T> or ObservableCollection<T>; both of these do what you want in standard ways.

You cannot do anything interesting by subclassing List<T> - the methods aren't virtual. Collection<T> is designed to be more extensible, but in this case everything you need is already provided (by BindingList<T>).

In particular, this provides:

  • IBindingList (used by many UI binding components, such as grids)
  • ListChanged - that your code can subscribe to for detailed notification

Upvotes: 5

Related Questions