5

What’s wrong with this code? Clicking button1 doesn’t cause the messageBox to appear.

public partial class Form1 : Form
{
    public ObservableCollection<string> aCollection2 = new ObservableCollection<string>();
    myClass mc = new myClass();

    public Form1()
    {
        InitializeComponent();

        aCollection2.Add("a");
        aCollection2.Add("b");
    }


    private void button1_Click(object sender, EventArgs e)
    {
        mc.myCollection = aCollection2;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        mc.myCollection.Clear();
    }
}

With myClass defined:

class myClass
{
    public ObservableCollection<string> myCollection = new ObservableCollection<string>();

    public myClass()
    {
        myCollection.CollectionChanged += Changed;
    }

    void Changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        MessageBox.Show(myCollection.Count.ToString());
    }
}

EDIT: When I add a 3rd button with:

private void button3_Click(object sender, EventArgs e)
{
    mc.myCollection.Add("a");
}

It does show the messageBox. And so does button2. But after clicking button1 – none will fire anymore. How come?

ispiro
  • 26,556
  • 38
  • 136
  • 291

1 Answers1

10

You added an event handler to the original ObservableCollection instance from your field initializer.
You never added an event handler to the new ObservableCollection instance from the form.
Since the original ObservableCollection never changes, your handler never runs.

This is one of the many reasons why collection properties should be read only (and they should be properties, not fields)

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 2
    @ispiro: Exactly. It only fires when you modify the **original** `ObservableCollection`, not after you replace it. – SLaks Oct 30 '11 at 23:06
  • 1
    Making the collection read-only revealed reassignments and saved me from lots of headaches. – Mert Akcakaya Jan 20 '15 at 08:32